File size: 1,726 Bytes
0e394c7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import sql from '../db';
import { Activity } from '../types/types';

export class ActivityModel {
  static async ensureTable(): Promise<void> {
    await sql`
      CREATE TABLE IF NOT EXISTS activities (
        id TEXT PRIMARY KEY,
        label TEXT NOT NULL,
        sort_order INT NOT NULL DEFAULT 0,
        is_visible BOOLEAN NOT NULL DEFAULT TRUE,
        created_at TIMESTAMP DEFAULT NOW()
      );
    `;

    // Seed if empty (idempotent)
    const [{ count }] = await sql<{ count: number }[]>`
      SELECT COUNT(*)::int AS count FROM activities;
    `;

    if (count === 0) {
      // Keep this list in the DB, not in the mobile app.
      // IDs should match values stored in routes.uses.
      await sql`
        INSERT INTO activities (id, label, sort_order, is_visible)
        VALUES
          ('downhill', 'Skiing', 10, TRUE),
          ('nordic', 'Cross-country', 20, TRUE),
          ('skitour', 'Ski Touring', 30, TRUE),
          ('snowboard', 'Snowboarding', 40, TRUE),
          ('hike', 'Hiking', 50, TRUE),
          ('snow_park', 'Snow Park', 60, TRUE),
          ('playground', 'Playground', 900, FALSE),
          ('sleigh', 'Sleigh', 910, FALSE)
        ON CONFLICT (id) DO NOTHING;
      `;
    }
  }

  static async listVisible(): Promise<Activity[]> {
    const rows = await sql<Activity[]>`
      SELECT id, label, sort_order, is_visible
      FROM activities
      WHERE is_visible = TRUE
      ORDER BY sort_order ASC, label ASC;
    `;
    return rows;
  }

  static async listAll(): Promise<Activity[]> {
    const rows = await sql<Activity[]>`
      SELECT id, label, sort_order, is_visible
      FROM activities
      ORDER BY sort_order ASC, label ASC;
    `;
    return rows;
  }
}