Initial commit: OnDeck project
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
commit
b036a93da2
139 changed files with 33198 additions and 0 deletions
72
ondeck/scripts/create-admin-user.ts
Normal file
72
ondeck/scripts/create-admin-user.ts
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import { PrismaClient } from '@prisma/client'
|
||||
import { PrismaPg } from '@prisma/adapter-pg'
|
||||
import { Pool } from 'pg'
|
||||
import { config } from 'dotenv'
|
||||
|
||||
config() // Load .env file
|
||||
|
||||
const pool = new Pool({ connectionString: process.env.DATABASE_URL })
|
||||
const adapter = new PrismaPg(pool)
|
||||
const prisma = new PrismaClient({ adapter })
|
||||
|
||||
async function createAdminUser(email: string, displayName: string) {
|
||||
console.log(`Creating admin user: ${email}`)
|
||||
|
||||
// Create or update the user
|
||||
const user = await prisma.user.upsert({
|
||||
where: { email },
|
||||
update: {
|
||||
displayName,
|
||||
isActive: true,
|
||||
},
|
||||
create: {
|
||||
email,
|
||||
displayName,
|
||||
isActive: true,
|
||||
},
|
||||
})
|
||||
console.log(`✅ User created/updated: ${user.id}`)
|
||||
|
||||
// Find the Admin role
|
||||
const adminRole = await prisma.role.findUnique({
|
||||
where: { name: 'Admin' },
|
||||
})
|
||||
|
||||
if (!adminRole) {
|
||||
console.error('❌ Admin role not found. Run seed first: npx prisma db seed')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Assign Admin role to user
|
||||
await prisma.userRole.upsert({
|
||||
where: {
|
||||
userId_roleId: {
|
||||
userId: user.id,
|
||||
roleId: adminRole.id,
|
||||
},
|
||||
},
|
||||
update: {},
|
||||
create: {
|
||||
userId: user.id,
|
||||
roleId: adminRole.id,
|
||||
},
|
||||
})
|
||||
console.log(`✅ Admin role assigned to ${email}`)
|
||||
|
||||
console.log('\n🎉 Admin user setup complete!')
|
||||
console.log(` Email: ${email}`)
|
||||
console.log(` User ID: ${user.id}`)
|
||||
}
|
||||
|
||||
const email = process.argv[2] || 'lorentz@wulfconsulting.com'
|
||||
const displayName = process.argv[3] || 'Lorentz'
|
||||
|
||||
createAdminUser(email, displayName)
|
||||
.catch((e) => {
|
||||
console.error('❌ Failed:', e)
|
||||
process.exit(1)
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect()
|
||||
await pool.end()
|
||||
})
|
||||
131
ondeck/scripts/import-shape-tasks.ts
Normal file
131
ondeck/scripts/import-shape-tasks.ts
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
import { PrismaClient } from '@prisma/client'
|
||||
import { PrismaPg } from '@prisma/adapter-pg'
|
||||
import { Pool } from 'pg'
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import * as dotenv from 'dotenv'
|
||||
|
||||
// Load environment variables
|
||||
dotenv.config()
|
||||
|
||||
const pool = new Pool({ connectionString: process.env.DATABASE_URL })
|
||||
const adapter = new PrismaPg(pool)
|
||||
const prisma = new PrismaClient({ adapter })
|
||||
|
||||
interface CsvRow {
|
||||
task: string
|
||||
daysAfterRenewal: number
|
||||
daysPriorToNextRenewal: number
|
||||
appliesTo: string
|
||||
active: boolean
|
||||
}
|
||||
|
||||
function parseCsv(content: string): CsvRow[] {
|
||||
const lines = content.trim().split('\n')
|
||||
// Skip header row, handle BOM
|
||||
const dataLines = lines.slice(1)
|
||||
|
||||
return dataLines.map((line) => {
|
||||
const parts = line.split(',')
|
||||
return {
|
||||
task: parts[0].trim(),
|
||||
daysAfterRenewal: parseInt(parts[1].trim()),
|
||||
daysPriorToNextRenewal: parseInt(parts[2].trim()),
|
||||
appliesTo: parts[3].trim(),
|
||||
active: parts[4].trim().toLowerCase() === 'yes',
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log('Importing SHAPE tasks from CSV...')
|
||||
|
||||
// Read CSV file
|
||||
const csvPath = path.join(__dirname, '../../dev/shapetasks.csv')
|
||||
const csvContent = fs.readFileSync(csvPath, 'utf-8')
|
||||
const rows = parseCsv(csvContent)
|
||||
|
||||
console.log(`Found ${rows.length} tasks to import`)
|
||||
|
||||
// Ensure Shape and Shape2 designations exist
|
||||
const shapeDesignation = await prisma.designation.upsert({
|
||||
where: { name: 'Shape' },
|
||||
update: {},
|
||||
create: {
|
||||
name: 'Shape',
|
||||
description: 'SHAPE program - primary designation for claims workflow tasks',
|
||||
color: 'designation-indigo',
|
||||
displayOrder: 10,
|
||||
isActive: true,
|
||||
},
|
||||
})
|
||||
console.log(`Shape designation ID: ${shapeDesignation.id}`)
|
||||
|
||||
const shape2Designation = await prisma.designation.upsert({
|
||||
where: { name: 'Shape2' },
|
||||
update: {},
|
||||
create: {
|
||||
name: 'Shape2',
|
||||
description: 'SHAPE program - secondary designation for claims workflow tasks',
|
||||
color: 'designation-violet',
|
||||
displayOrder: 11,
|
||||
isActive: true,
|
||||
},
|
||||
})
|
||||
console.log(`Shape2 designation ID: ${shape2Designation.id}`)
|
||||
|
||||
// Import task templates
|
||||
let created = 0
|
||||
let skipped = 0
|
||||
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const row = rows[i]
|
||||
const designationId = row.appliesTo === 'Shape'
|
||||
? shapeDesignation.id
|
||||
: shape2Designation.id
|
||||
|
||||
// Check if template already exists with same name and designation
|
||||
const existing = await prisma.taskTemplate.findFirst({
|
||||
where: {
|
||||
name: row.task,
|
||||
designationId: designationId,
|
||||
},
|
||||
})
|
||||
|
||||
if (existing) {
|
||||
console.log(`Skipping existing: "${row.task}" (${row.appliesTo})`)
|
||||
skipped++
|
||||
continue
|
||||
}
|
||||
|
||||
// Create template using PRE_RENEWAL timing with negative offset
|
||||
await prisma.taskTemplate.create({
|
||||
data: {
|
||||
name: row.task,
|
||||
description: null,
|
||||
department: 'CLAIMS',
|
||||
timing: 'PRE_RENEWAL',
|
||||
daysOffset: -row.daysPriorToNextRenewal, // Negative for pre-renewal
|
||||
defaultPriority: 'MEDIUM',
|
||||
isActive: row.active,
|
||||
displayOrder: i + 1,
|
||||
designationId: designationId,
|
||||
},
|
||||
})
|
||||
|
||||
console.log(`Created: "${row.task}" (${row.appliesTo}, ${row.daysPriorToNextRenewal} days before renewal)`)
|
||||
created++
|
||||
}
|
||||
|
||||
console.log(`\nImport complete: ${created} created, ${skipped} skipped`)
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error('Import failed:', e)
|
||||
process.exit(1)
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect()
|
||||
await pool.end()
|
||||
})
|
||||
22
ondeck/scripts/run-sync.ts
Normal file
22
ondeck/scripts/run-sync.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import 'dotenv/config'
|
||||
import { runSync } from '../src/lib/sync/sync-engine'
|
||||
|
||||
async function main() {
|
||||
console.log('Starting manual sync...')
|
||||
|
||||
const result = await runSync(undefined, false) // Full sync, not incremental
|
||||
|
||||
if (result.success) {
|
||||
console.log('\n✅ Sync completed successfully!')
|
||||
console.log('Stats:', JSON.stringify(result.stats, null, 2))
|
||||
} else {
|
||||
console.error('\n❌ Sync failed:', result.error)
|
||||
console.log('Stats:', JSON.stringify(result.stats, null, 2))
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error('Fatal error:', error)
|
||||
process.exit(1)
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue