@quickscores/chat 0.1.0 → 0.1.2

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.
package/README.md CHANGED
@@ -1,158 +1,38 @@
1
- # QuickScores Chat Service
1
+ # @quickscores/chat
2
2
 
3
- Supabase-backed chat for QuickScores. Consumers: React Native (Android/iOS) and web app.
3
+ Shared TypeScript types and Zod schemas for the QuickScores chat API. Use from React Native or web apps that call the chat endpoints.
4
4
 
5
- ## What’s in this repo
6
-
7
- - **Supabase**: config, migrations, and Edge Functions for chat (DB, RLS, Realtime).
8
- - **Shared types**: TypeScript types and Zod schemas in `src/types/` for use by RN and web clients.
9
-
10
- ## Prerequisites
11
-
12
- - [Supabase CLI](https://supabase.com/docs/guides/cli) (`npm i -g supabase` or `npx supabase`)
13
- - Node.js 20+
14
- - A [Supabase project](https://supabase.com/dashboard) (for remote; optional for local-only)
15
-
16
- ## Setup
5
+ ## Install
17
6
 
18
7
  ```bash
19
- npm install
8
+ pnpm add @quickscores/chat
20
9
  ```
21
10
 
22
- ### Local Supabase (optional)
23
-
24
- ```bash
25
- npx supabase start
11
+ ## Usage
12
+
13
+ ```ts
14
+ import {
15
+ threadSchema,
16
+ threadKindSchema,
17
+ threadListRowSchema,
18
+ messageSchema,
19
+ type Thread,
20
+ type ThreadKind,
21
+ type ThreadListRow,
22
+ type Message,
23
+ type CreateThreadBody,
24
+ type SendMessageBody,
25
+ type ThreadResponse,
26
+ type MessageResponse,
27
+ type ErrorResponse,
28
+ } from "@quickscores/chat";
26
29
  ```
27
30
 
28
- Use the printed URLs for local API, Studio, and DB. Link to a remote project when ready:
29
-
30
- ```bash
31
- npx supabase link --project-ref <your-project-ref>
32
- ```
33
-
34
- ### Migrations
35
-
36
- - Create: put SQL in `supabase/migrations/` with timestamped names (e.g. `20240202120000_create_chat_tables.sql`), or use `npm run db:diff` after changing schema locally.
37
- - Apply locally: `npx supabase db reset` (reset + seed) or run migrations manually.
38
- - Push to remote: `npm run db:migrate` (or `npx supabase db push`).
39
-
40
- ### Deploy to Supabase
41
-
42
- 1. **Create a project** at [supabase.com/dashboard](https://supabase.com/dashboard) if you don’t have one. Note the **Project ref** (in Settings → General).
43
-
44
- 2. **Link** the repo to that project (one-time):
45
- ```bash
46
- npx supabase link --project-ref <your-project-ref>
47
- ```
48
- Use your database password when prompted (from Dashboard → Settings → Database).
49
-
50
- 3. **Push migrations** (schema + RLS):
51
- ```bash
52
- npm run db:migrate
53
- ```
54
- or `npx supabase db push`.
55
-
56
- 4. **Deploy Edge Functions** (chat REST API):
57
- ```bash
58
- npx supabase functions deploy
59
- ```
60
- This deploys all functions in `supabase/functions/` (e.g. `chat-thread`, `chat-send-message`, `chat-mark-read`). To deploy a single function: `npx supabase functions deploy chat-thread`.
61
-
62
- 5. **Set secrets** (if your functions need them): in Dashboard → Edge Functions → Secrets, or:
63
- ```bash
64
- npx supabase secrets set SUPABASE_SERVICE_ROLE_KEY=<your-service-role-key>
65
- ```
66
- The hosted project already has `SUPABASE_URL` and `SUPABASE_SERVICE_ROLE_KEY` set by default for deployed functions; you only need to add custom secrets.
67
-
68
- Your API base URL will be `https://<project-ref>.supabase.co/functions/v1`. Use that in clients instead of `http://127.0.0.1:54321/functions/v1`.
69
-
70
- ## Scripts
71
-
72
- | Script | Description |
73
- |-----------------|--------------------------------------|
74
- | `npm run db:start` | Start local Supabase stack |
75
- | `npm run db:stop` | Stop local Supabase |
76
- | `npm run db:reset` | Reset DB and run migrations + seed |
77
- | `npm run db:migrate`| Push migrations to linked project |
78
- | `npm run db:diff` | Generate migration from schema diff |
79
- | `npm run build` | Build types package to `dist/` (for publish) |
80
- | `npm run types:check` | TypeScript check (no emit) |
81
- | `npm run lint` | Prettier check |
82
- | `npm run lint:fix` | Prettier fix |
83
-
84
- ## Using shared types in the app
85
-
86
- From the React Native (or web) app:
87
-
88
- 1. **Workspace / link** (if in a monorepo or same parent repo):
89
- - Add in the app’s `package.json`: `"@quickscores/chat": "file:../chat"` (or your path).
90
- - In this repo, run `npm run build` so `dist/` is present (the package entry point is the built output).
91
- - Then: `import { threadSchema, type Thread, type Message, type ThreadListRow } from "@quickscores/chat";`
92
- - REST request/response types: `CreateThreadBody`, `SendMessageBody`, `ThreadResponse`, `MessageResponse`, `ErrorResponse`, etc. (see `src/types/api.ts`).
93
- 2. **From a registry**: Publish the types package (see below), then add `"@quickscores/chat": "^0.1.0"` and run `npm install`.
94
-
95
- Types are aligned with the Supabase schema and [docs/api-chat.md](docs/api-chat.md): `Thread` (chat_threads), `Message` (chat_messages), `ThreadListRow` (chat_thread_list view).
96
-
97
- ### Publishing the types package to a registry
98
-
99
- The entire `src/` tree is built to `dist/` and only `dist/` is published (`"files": ["dist"]`). Supabase config, migrations, Edge Functions, scripts, and docs are not included in the tarball.
100
-
101
- 1. **Build**: `npm run build` (or it runs automatically via `prepublishOnly` when you publish).
102
- 2. **Allow publishing**: In `package.json`, set `"private": false` (or remove the `"private"` field).
103
- 3. **Publish to npm** (see [Publishing to npm](#publishing-to-npm) below).
104
-
105
- Consumers then install with `"@quickscores/chat": "^0.1.0"` and import as before; they get types and Zod runtime from the published tarball only.
106
-
107
- #### Publishing to npm
108
-
109
- 1. **Create the scope** (one-time): [npmjs.com/org/create](https://www.npmjs.com/org/create) and create the `quickscores` org (or use an existing org that will own the package).
110
-
111
- 2. **Log in** (if you aren’t already):
112
- ```bash
113
- npm login
114
- ```
115
-
116
- 3. **Allow publishing**: In `package.json`, set `"private": false` (or remove the `"private"` field).
117
-
118
- 4. **Publish** (build runs automatically via `prepublishOnly`):
119
- ```bash
120
- npm publish --access public
121
- ```
122
- Scoped packages (`@quickscores/chat`) are private by default; `--access public` makes them installable by anyone without a paid plan.
123
-
124
- After that, anyone can run `npm install @quickscores/chat` with no extra config or tokens.
125
-
126
- ## Project layout
127
-
128
- ```
129
- chat/
130
- ├── supabase/
131
- │ ├── config.toml # Local Supabase config
132
- │ ├── migrations/ # SQL migrations (chat tables, RLS)
133
- │ ├── functions/ # Edge Functions (chat REST API)
134
- │ └── seed.sql # Optional seed data
135
- ├── src/
136
- │ └── types/ # Shared TypeScript + Zod (Thread, Message, ThreadListRow, REST API types)
137
- ├── docs/
138
- │ ├── prd/ # Product requirements
139
- │ └── api-chat.md # Chat REST API reference
140
- ├── package.json
141
- ├── tsconfig.json
142
- └── README.md
143
- ```
144
-
145
- ## Chat REST API
146
-
147
- We do **not** use Postgres RPCs for chat. The API is implemented as **REST HTTP endpoints** using Supabase Edge Functions: each action (get/create thread, send message, mark read) is a separate Edge Function. Clients use normal HTTP (e.g. `fetch` or `axios`).
148
-
149
- - **Docs:** [docs/api-chat.md](docs/api-chat.md)
150
- - **Endpoints:** `POST /functions/v1/chat-thread` (get/create thread), `chat-league-room`, `chat-team-room`, `chat-send-message`, `chat-mark-read`
151
- - **Auth:** Not enforced yet; use header `X-User-Id` (or body `user_id`) to identify the caller. Add JWT auth later.
31
+ - **Domain types:** `Thread`, `ThreadKind`, `ThreadListRow`, `Message` use with the matching Zod schemas for validation.
32
+ - **API types:** `CreateThreadBody`, `LeagueRoomBody`, `TeamRoomBody`, `SendMessageBody`, `MarkReadBody`, `ThreadResponse`, `MessageResponse`, `MarkReadResponse`, `ErrorResponse` — for request/response typing.
152
33
 
153
- Run locally: `npx supabase start` then `npx supabase functions serve`. See [docs/api-chat.md](docs/api-chat.md#testing) for how to test (curl examples and `npm run test:api`).
34
+ Types and schemas stay in sync with the chat backend and [API docs](https://github.com/quickscores/App2.0-Chat/blob/main/docs/api-chat.md) in the source repo.
154
35
 
155
- ## Next steps
36
+ ## Repository
156
37
 
157
- 1. Add auth: validate JWT in Edge Functions and use `auth.uid()` instead of `X-User-Id`.
158
- 2. In the RN/app, call the chat endpoints and use types from `@quickscores/chat` (see [docs/api-chat.md](docs/api-chat.md)).
38
+ Source and backend docs: [github.com/quickscores/App2.0-Chat](https://github.com/quickscores/App2.0-Chat). If you’re developing this package or the chat service, see [DEVELOPING.md](https://github.com/quickscores/App2.0-Chat/blob/main/DEVELOPING.md) in the repo.
@@ -29,7 +29,7 @@ export declare const threadSchema: z.ZodObject<{
29
29
  }, z.core.$strip>;
30
30
  export type Thread = z.infer<typeof threadSchema>;
31
31
  /**
32
- * Thread list row – one row per thread from chat_thread_list view.
32
+ * Thread list row – one row from GET /chat-threads (includes channel and optional team/league fields).
33
33
  */
34
34
  export declare const threadListRowSchema: z.ZodObject<{
35
35
  thread_id: z.ZodString;
@@ -47,8 +47,15 @@ export declare const threadListRowSchema: z.ZodObject<{
47
47
  last_read_message_id: z.ZodNullable<z.ZodString>;
48
48
  last_message_at: z.ZodNullable<z.ZodString>;
49
49
  last_message_preview: z.ZodNullable<z.ZodString>;
50
+ last_message_by: z.ZodNullable<z.ZodNumber>;
50
51
  unread_count: z.ZodNumber;
51
52
  other_participant_ids: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
53
+ team_id: z.ZodNullable<z.ZodNumber>;
54
+ league_id: z.ZodNullable<z.ZodNumber>;
55
+ team_name: z.ZodNullable<z.ZodString>;
56
+ league_name: z.ZodNullable<z.ZodString>;
57
+ sport_type: z.ZodNullable<z.ZodString>;
58
+ channel: z.ZodString;
52
59
  }, z.core.$strip>;
53
60
  export type ThreadListRow = z.infer<typeof threadListRowSchema>;
54
61
  //# sourceMappingURL=thread.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../src/types/thread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;EAA4C,CAAC;AAC1E,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;iBAQvB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;iBAa9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
1
+ {"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../src/types/thread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;EAA4C,CAAC;AAC1E,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;iBAQvB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;iBAoB9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
@@ -20,7 +20,7 @@ exports.threadSchema = zod_1.z.object({
20
20
  created_at: zod_1.z.string(),
21
21
  });
22
22
  /**
23
- * Thread list row – one row per thread from chat_thread_list view.
23
+ * Thread list row – one row from GET /chat-threads (includes channel and optional team/league fields).
24
24
  */
25
25
  exports.threadListRowSchema = zod_1.z.object({
26
26
  thread_id: zod_1.z.string().uuid(),
@@ -33,6 +33,13 @@ exports.threadListRowSchema = zod_1.z.object({
33
33
  last_read_message_id: zod_1.z.string().uuid().nullable(),
34
34
  last_message_at: zod_1.z.string().nullable(),
35
35
  last_message_preview: zod_1.z.string().nullable(),
36
+ last_message_by: zod_1.z.number().int().nullable(),
36
37
  unread_count: zod_1.z.number().int().min(0),
37
38
  other_participant_ids: zod_1.z.array(zod_1.z.number().int()).nullable(),
39
+ team_id: zod_1.z.number().int().nullable(),
40
+ league_id: zod_1.z.number().int().nullable(),
41
+ team_name: zod_1.z.string().nullable(),
42
+ league_name: zod_1.z.string().nullable(),
43
+ sport_type: zod_1.z.string().nullable(),
44
+ channel: zod_1.z.string(),
38
45
  });
package/package.json CHANGED
@@ -1,25 +1,13 @@
1
1
  {
2
2
  "name": "@quickscores/chat",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "private": false,
5
5
  "description": "Shared chat types and Zod schemas for QuickScores (RN, web)",
6
6
  "main": "./dist/types/index.js",
7
7
  "types": "./dist/types/index.d.ts",
8
- "files": ["dist"],
9
- "scripts": {
10
- "build": "tsc -p tsconfig.build.json",
11
- "prepublishOnly": "npm run build",
12
- "db:start": "supabase start",
13
- "db:stop": "supabase stop",
14
- "db:reset": "supabase db reset",
15
- "db:migrate": "supabase db push",
16
- "db:diff": "supabase db diff -f",
17
- "types:check": "tsc --noEmit",
18
- "lint": "prettier --check \"src/**/*.ts\" \"scripts/**/*.ts\" \"supabase/functions/**/*.ts\"",
19
- "lint:fix": "prettier --write \"src/**/*.ts\" \"scripts/**/*.ts\" \"supabase/functions/**/*.ts\"",
20
- "test:api": "tsx scripts/test-chat-api.ts",
21
- "test:league-team-rooms": "tsx scripts/test-league-team-rooms.ts"
22
- },
8
+ "files": [
9
+ "dist"
10
+ ],
23
11
  "dependencies": {
24
12
  "zod": "4.3.5"
25
13
  },
@@ -50,5 +38,19 @@
50
38
  "import": "./dist/types/index.js",
51
39
  "default": "./dist/types/index.js"
52
40
  }
41
+ },
42
+ "scripts": {
43
+ "build": "tsc -p tsconfig.build.json",
44
+ "db:start": "supabase start",
45
+ "db:stop": "supabase stop",
46
+ "db:reset": "supabase db reset",
47
+ "db:migrate": "supabase db push",
48
+ "db:diff": "supabase db diff -f",
49
+ "functions:serve": "supabase functions serve --env-file supabase/functions/.env",
50
+ "types:check": "tsc --noEmit",
51
+ "lint": "prettier --check \"src/**/*.ts\" \"scripts/**/*.ts\" \"supabase/functions/**/*.ts\"",
52
+ "lint:fix": "prettier --write \"src/**/*.ts\" \"scripts/**/*.ts\" \"supabase/functions/**/*.ts\"",
53
+ "test:api": "tsx scripts/test-chat-api.ts",
54
+ "test:league-team-rooms": "tsx scripts/test-league-team-rooms.ts"
53
55
  }
54
- }
56
+ }