@proletariat/cli 0.3.30 → 0.3.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -218,6 +218,37 @@ export function runMigrations(db) {
218
218
  // Table may already be dropped
219
219
  }
220
220
  }
221
+ // Migration: Add position column to tickets table (TKT-965)
222
+ if (!ticketsColumnNames.has('position')) {
223
+ try {
224
+ db.exec(`ALTER TABLE ${T.tickets} ADD COLUMN position INTEGER NOT NULL DEFAULT 0`);
225
+ db.exec(`CREATE INDEX IF NOT EXISTS idx_pmo_tickets_status_position ON ${T.tickets}(status_id, position)`);
226
+ // Backfill existing tickets with gapped positions (1000, 2000, ...) per status
227
+ const statuses = db.prepare(`SELECT DISTINCT status_id FROM ${T.tickets} WHERE status_id IS NOT NULL`).all();
228
+ const getTicketsForStatus = db.prepare(`
229
+ SELECT id FROM ${T.tickets} WHERE status_id = ?
230
+ ORDER BY
231
+ CASE priority
232
+ WHEN 'P0' THEN 0
233
+ WHEN 'P1' THEN 1
234
+ WHEN 'P2' THEN 2
235
+ WHEN 'P3' THEN 3
236
+ ELSE 4
237
+ END,
238
+ created_at ASC
239
+ `);
240
+ const updatePosition = db.prepare(`UPDATE ${T.tickets} SET position = ? WHERE id = ?`);
241
+ for (const { status_id } of statuses) {
242
+ const tickets = getTicketsForStatus.all(status_id);
243
+ for (let i = 0; i < tickets.length; i++) {
244
+ updatePosition.run((i + 1) * 1000, tickets[i].id);
245
+ }
246
+ }
247
+ }
248
+ catch {
249
+ // Column may already exist
250
+ }
251
+ }
221
252
  // Migration: Reassign orphaned tickets (TKT-940)
222
253
  // Tickets with project_id that doesn't match any existing project are "orphaned".
223
254
  // This can happen when a 'default' project never existed or was deleted.