@lightupai/polaris 0.0.5 → 0.0.6

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.
@@ -0,0 +1,71 @@
1
+ import type { Sql } from "../src/service/db";
2
+
3
+ /**
4
+ * Reset test data: drop and recreate all tables using the canonical schema.
5
+ * This ensures tests always match the current schema in db.ts.
6
+ */
7
+ export async function resetTestData(sql: Sql): Promise<void> {
8
+ await sql`DROP TABLE IF EXISTS events`;
9
+ await sql`DROP TABLE IF EXISTS sessions`;
10
+ await sql`DROP TABLE IF EXISTS projects`;
11
+ await sql`DROP TABLE IF EXISTS users`;
12
+ await sql`DROP TABLE IF EXISTS orgs`;
13
+ await sql`
14
+ CREATE TABLE orgs (
15
+ id TEXT PRIMARY KEY,
16
+ name TEXT NOT NULL,
17
+ slug TEXT UNIQUE,
18
+ domain TEXT,
19
+ slack_team_id TEXT,
20
+ slack_bot_token TEXT,
21
+ slack_system_channel_id TEXT,
22
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
23
+ )
24
+ `;
25
+ await sql`
26
+ CREATE TABLE users (
27
+ id TEXT PRIMARY KEY,
28
+ email TEXT NOT NULL UNIQUE,
29
+ name TEXT NOT NULL,
30
+ org_id TEXT NOT NULL REFERENCES orgs(id),
31
+ participant_id TEXT NOT NULL,
32
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now()
33
+ )
34
+ `;
35
+ await sql`
36
+ CREATE TABLE projects (
37
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
38
+ org_id TEXT NOT NULL REFERENCES orgs(id),
39
+ name TEXT NOT NULL,
40
+ slack_channel_id TEXT,
41
+ slack_channel_name TEXT,
42
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
43
+ UNIQUE (org_id, name)
44
+ )
45
+ `;
46
+ await sql`
47
+ CREATE TABLE sessions (
48
+ name TEXT NOT NULL,
49
+ project_id UUID NOT NULL REFERENCES projects(id),
50
+ org_id TEXT NOT NULL,
51
+ driver TEXT,
52
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
53
+ PRIMARY KEY (project_id, name)
54
+ )
55
+ `;
56
+ await sql`
57
+ CREATE TABLE events (
58
+ id UUID PRIMARY KEY,
59
+ org_id TEXT NOT NULL,
60
+ project_id UUID NOT NULL REFERENCES projects(id),
61
+ session TEXT NOT NULL,
62
+ timestamp TIMESTAMPTZ NOT NULL,
63
+ source TEXT NOT NULL,
64
+ sender TEXT NOT NULL,
65
+ payload JSONB NOT NULL
66
+ )
67
+ `;
68
+ await sql`CREATE INDEX idx_events_project ON events(project_id, timestamp)`;
69
+ await sql`CREATE INDEX idx_events_session ON events(project_id, session, timestamp)`;
70
+ await sql`INSERT INTO orgs (id, name) VALUES ('default', 'Default') ON CONFLICT DO NOTHING`;
71
+ }
@@ -2,6 +2,7 @@ import { describe, expect, test, beforeAll, afterAll, beforeEach } from "bun:tes
2
2
  import { startServer } from "../src/service/server";
3
3
  import type { Sql } from "../src/service/db";
4
4
  import type { Server } from "bun";
5
+ import { resetTestData } from "./helpers";
5
6
 
6
7
  const DATABASE_URL = process.env.DATABASE_URL ?? "postgres://polaris:polaris@localhost:5432/polaris_test";
7
8
 
@@ -21,19 +22,7 @@ afterAll(async () => {
21
22
  });
22
23
 
23
24
  beforeEach(async () => {
24
- await sql`DROP TABLE IF EXISTS events`;
25
- await sql`DROP TABLE IF EXISTS sessions`;
26
- await sql`DROP TABLE IF EXISTS projects`;
27
- await sql`DROP TABLE IF EXISTS users`;
28
- await sql`DROP TABLE IF EXISTS orgs`;
29
- await sql`CREATE TABLE IF NOT EXISTS orgs (id TEXT PRIMARY KEY, name TEXT NOT NULL, slug TEXT UNIQUE, domain TEXT, slack_team_id TEXT, slack_bot_token TEXT, slack_system_channel_id TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now())`;
30
- await sql`CREATE TABLE IF NOT EXISTS users (id TEXT PRIMARY KEY, email TEXT NOT NULL UNIQUE, name TEXT NOT NULL, org_id TEXT NOT NULL REFERENCES orgs(id), participant_id TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now())`;
31
- await sql`CREATE TABLE IF NOT EXISTS projects (name TEXT NOT NULL, org_id TEXT NOT NULL REFERENCES orgs(id), created_at TIMESTAMPTZ NOT NULL DEFAULT now(), PRIMARY KEY (org_id, name))`;
32
- await sql`CREATE TABLE IF NOT EXISTS sessions (name TEXT NOT NULL, project TEXT NOT NULL, org_id TEXT NOT NULL, driver TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), PRIMARY KEY (org_id, project, name), FOREIGN KEY (org_id, project) REFERENCES projects(org_id, name))`;
33
- await sql`CREATE TABLE IF NOT EXISTS events (id UUID PRIMARY KEY, org_id TEXT NOT NULL, project TEXT NOT NULL, session TEXT NOT NULL, timestamp TIMESTAMPTZ NOT NULL, source TEXT NOT NULL, sender TEXT NOT NULL, payload JSONB NOT NULL)`;
34
- await sql`CREATE INDEX IF NOT EXISTS idx_events_project ON events(org_id, project, timestamp)`;
35
- await sql`CREATE INDEX IF NOT EXISTS idx_events_session ON events(org_id, project, session, timestamp)`;
36
- await sql`INSERT INTO orgs (id, name) VALUES ('default', 'Default') ON CONFLICT DO NOTHING`;
25
+ await resetTestData(sql);
37
26
  });
38
27
 
39
28
  async function post(path: string, body: unknown) {
@@ -208,12 +208,12 @@ describe("PolarisEvent", () => {
208
208
 
209
209
  describe("Project", () => {
210
210
  test("parses valid project", () => {
211
- const result = Project.parse({ name: "pj", created_at: "2026-06-05T10:00:00.000Z" });
211
+ const result = Project.parse({ id: "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", name: "pj", created_at: "2026-06-05T10:00:00.000Z" });
212
212
  expect(result.name).toBe("pj");
213
213
  });
214
214
 
215
215
  test("rejects empty name", () => {
216
- expect(() => Project.parse({ name: "", created_at: "2026-06-05T10:00:00.000Z" })).toThrow();
216
+ expect(() => Project.parse({ id: "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", name: "", created_at: "2026-06-05T10:00:00.000Z" })).toThrow();
217
217
  });
218
218
  });
219
219
 
package/tests/web.test.ts CHANGED
@@ -12,16 +12,17 @@ import {
12
12
  import { createApp } from "../src/web/app";
13
13
  import { createDb, createOrg, createUser, type Sql } from "../src/service/db";
14
14
  import { createToken } from "../src/service/auth";
15
+ import { resetTestData } from "./helpers";
15
16
 
16
17
  const DATABASE_URL = process.env.DATABASE_URL ?? "postgres://polaris:polaris@localhost:5432/polaris_test";
17
18
 
18
19
  // --- View context helpers ---
19
20
 
20
21
  const base = { token: "test-token", userName: "Manu Bansal", orgName: "Lightup", orgSlug: "lightup-data" as string | null, email: "manu@lightup.ai" };
21
- const fresh = { ...base, orgSlug: null, slackConnected: false, cliInstalled: false, hasConnectedSession: false };
22
- const slackDone = { ...base, slackConnected: true, cliInstalled: false, hasConnectedSession: false };
23
- const cliDone = { ...base, slackConnected: true, cliInstalled: true, hasConnectedSession: false };
24
- const allDone = { ...base, slackConnected: true, cliInstalled: true, hasConnectedSession: true };
22
+ const fresh = { ...base, orgSlug: null, slackConnected: false, cliInstalled: false, hasConnectedSession: false, totalPrompts: 0 };
23
+ const slackDone = { ...base, slackConnected: true, cliInstalled: false, hasConnectedSession: false, totalPrompts: 0 };
24
+ const cliDone = { ...base, slackConnected: true, cliInstalled: true, hasConnectedSession: false, totalPrompts: 0 };
25
+ const allDone = { ...base, slackConnected: true, cliInstalled: true, hasConnectedSession: true, totalPrompts: 42 };
25
26
 
26
27
  // --- Setup view ---
27
28
 
@@ -35,7 +36,7 @@ describe("renderSetupView", () => {
35
36
  // Connect Slack button is present
36
37
  expect(html).toContain("Connect Slack");
37
38
  // Install CLI command is present
38
- expect(html).toContain("npx @lightupai/polaris login");
39
+ expect(html).toContain("npx @lightupai/polaris");
39
40
  // Connect session command is present
40
41
  expect(html).toContain("/polaris join my-project my-session");
41
42
  });
@@ -52,7 +53,7 @@ describe("renderSetupView", () => {
52
53
  const highlightIdx = html.indexOf("border-polaris-300");
53
54
  expect(highlightIdx).toBeGreaterThan(devicesIdx);
54
55
  // Install CLI command present
55
- expect(html).toContain("npx @lightupai/polaris login");
56
+ expect(html).toContain("npx @lightupai/polaris");
56
57
  });
57
58
 
58
59
  test("cli done: floor and devices done, sessions is highlighted", () => {
@@ -80,29 +81,23 @@ describe("renderSetupView", () => {
80
81
  describe("renderActiveView", () => {
81
82
  test("shows compact floor bar", () => {
82
83
  const html = renderActiveView(allDone, mockActiveSessions, mockProjects, mockDevices);
83
- expect(html).toContain("Live");
84
+ expect(html).toContain("Connected");
84
85
  // No Connect Slack button
85
86
  expect(html).not.toContain("Connect Slack");
86
87
  });
87
88
 
88
- test("shows session cards with roles", () => {
89
- const html = renderActiveView(allDone, mockActiveSessions, mockProjects, mockDevices);
90
- expect(html).toContain("polaris/auth");
91
- expect(html).toContain("polaris/slack-bridge");
92
- // Role badges are rendered (Advisor shown when participant ID derivation
93
- // from display name doesn't match fixture — expected for mock data)
94
- expect(html).toContain("Advisor");
95
- });
96
-
97
- test("shows session descriptions and event counts", () => {
89
+ test("shows sessions nested under projects", () => {
98
90
  const html = renderActiveView(allDone, mockActiveSessions, mockProjects, mockDevices);
99
- expect(html).toContain("Google SSO + JWT auth");
100
- expect(html).toContain("42 events");
91
+ // Session names shown within project cards
92
+ expect(html).toContain("auth");
93
+ expect(html).toContain("slack-bridge");
94
+ // Project names as card headers
95
+ expect(html).toContain("polaris");
96
+ expect(html).toContain("data-pipeline");
101
97
  });
102
98
 
103
- test("shows other participants in sessions", () => {
99
+ test("shows driver info in session rows", () => {
104
100
  const html = renderActiveView(allDone, mockActiveSessions, mockProjects, mockDevices);
105
- expect(html).toContain("agent:security-reviewer");
106
101
  expect(html).toContain("user:krishna");
107
102
  });
108
103
 
@@ -263,16 +258,7 @@ describe("routes", () => {
263
258
  });
264
259
 
265
260
  beforeEach(async () => {
266
- await sql`DROP TABLE IF EXISTS events`;
267
- await sql`DROP TABLE IF EXISTS sessions`;
268
- await sql`DROP TABLE IF EXISTS projects`;
269
- await sql`DROP TABLE IF EXISTS users`;
270
- await sql`DROP TABLE IF EXISTS orgs`;
271
- await sql`CREATE TABLE IF NOT EXISTS orgs (id TEXT PRIMARY KEY, name TEXT NOT NULL, slug TEXT UNIQUE, domain TEXT, slack_team_id TEXT, slack_bot_token TEXT, slack_system_channel_id TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now())`;
272
- await sql`CREATE TABLE IF NOT EXISTS users (id TEXT PRIMARY KEY, email TEXT NOT NULL UNIQUE, name TEXT NOT NULL, org_id TEXT NOT NULL REFERENCES orgs(id), participant_id TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now())`;
273
- await sql`CREATE TABLE IF NOT EXISTS projects (name TEXT NOT NULL, org_id TEXT NOT NULL REFERENCES orgs(id), created_at TIMESTAMPTZ NOT NULL DEFAULT now(), PRIMARY KEY (org_id, name))`;
274
- await sql`CREATE TABLE IF NOT EXISTS sessions (name TEXT NOT NULL, project TEXT NOT NULL, org_id TEXT NOT NULL, driver TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), PRIMARY KEY (org_id, project, name), FOREIGN KEY (org_id, project) REFERENCES projects(org_id, name))`;
275
- await sql`CREATE TABLE IF NOT EXISTS events (id UUID PRIMARY KEY, org_id TEXT NOT NULL, project TEXT NOT NULL, session TEXT NOT NULL, timestamp TIMESTAMPTZ NOT NULL, source TEXT NOT NULL, sender TEXT NOT NULL, payload JSONB NOT NULL)`;
261
+ await resetTestData(sql);
276
262
 
277
263
  await createOrg(sql, "test-org", "Test Org", "test.com");
278
264
  await createUser(sql, "user-1", "test@test.com", "Test User", "test-org", "user:test");