create-svc 0.1.10 → 0.1.11

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.
Files changed (168) hide show
  1. package/README.md +46 -43
  2. package/bin/create-service.mjs +2 -0
  3. package/package.json +12 -9
  4. package/src/cli.test.ts +28 -10
  5. package/src/cli.ts +195 -30
  6. package/src/git-bootstrap.test.ts +40 -0
  7. package/src/git-bootstrap.ts +110 -0
  8. package/src/naming.test.ts +1 -0
  9. package/src/naming.ts +23 -0
  10. package/src/post-scaffold.test.ts +19 -0
  11. package/src/post-scaffold.ts +17 -4
  12. package/src/profiles.ts +2 -5
  13. package/src/scaffold.test.ts +231 -40
  14. package/src/scaffold.ts +84 -29
  15. package/src/vault.test.ts +61 -1
  16. package/src/vault.ts +77 -15
  17. package/templates/shared/.github/workflows/ci.yml +2 -1
  18. package/templates/shared/.github/workflows/deploy.yml +2 -0
  19. package/templates/shared/README.md +124 -47
  20. package/templates/shared/grafana/alerts.yaml +54 -0
  21. package/templates/shared/grafana/waitlist-dashboard.json +63 -0
  22. package/templates/shared/scripts/authctl.ts +231 -0
  23. package/templates/shared/scripts/cloudrun/bootstrap.ts +14 -5
  24. package/templates/shared/scripts/cloudrun/cleanup.ts +64 -4
  25. package/templates/shared/scripts/cloudrun/cli.ts +324 -7
  26. package/templates/shared/scripts/cloudrun/config.ts +11 -4
  27. package/templates/shared/scripts/cloudrun/deploy.ts +0 -4
  28. package/templates/shared/scripts/cloudrun/lib.ts +174 -41
  29. package/templates/shared/scripts/cloudrun/neon.ts +45 -0
  30. package/templates/shared/scripts/dev.ts +22 -0
  31. package/templates/shared/scripts/ensure-local-db.ts +3 -0
  32. package/templates/shared/scripts/local-docker.ts +63 -0
  33. package/templates/shared/scripts/local-env.ts +27 -0
  34. package/templates/shared/scripts/seed.ts +73 -0
  35. package/templates/shared/scripts/wait-for-db.ts +32 -0
  36. package/templates/shared/service.config.ts +59 -0
  37. package/templates/shared/service.yaml +24 -44
  38. package/templates/targets/workers/.github/workflows/ci.yml +19 -0
  39. package/templates/targets/workers/.github/workflows/deploy.yml +19 -0
  40. package/templates/targets/workers/Makefile +33 -0
  41. package/templates/targets/workers/README.md +75 -0
  42. package/templates/targets/workers/package.json +35 -0
  43. package/templates/targets/workers/scripts/workers/cli.ts +397 -0
  44. package/templates/targets/workers/src/auth.ts +178 -0
  45. package/templates/targets/workers/src/index.ts +198 -0
  46. package/templates/targets/workers/src/storage.ts +370 -0
  47. package/templates/targets/workers/test/app.test.ts +108 -0
  48. package/templates/targets/workers/tsconfig.json +11 -0
  49. package/templates/targets/workers/wrangler.toml +24 -0
  50. package/templates/variants/bun-connectrpc/Makefile +14 -8
  51. package/templates/variants/bun-connectrpc/gen/protos/waitlist/v1/waitlist_pb.ts +424 -0
  52. package/templates/variants/bun-connectrpc/migrations/0000_init.sql +12 -55
  53. package/templates/variants/bun-connectrpc/package.json +12 -5
  54. package/templates/variants/bun-connectrpc/protos/waitlist/v1/waitlist.proto +91 -0
  55. package/templates/variants/bun-connectrpc/scripts/codegen.ts +1 -1
  56. package/templates/variants/bun-connectrpc/scripts/migrate.ts +4 -1
  57. package/templates/variants/bun-connectrpc/src/auth.ts +200 -0
  58. package/templates/variants/bun-connectrpc/src/db/repository.ts +67 -420
  59. package/templates/variants/bun-connectrpc/src/db/schema.ts +15 -64
  60. package/templates/variants/bun-connectrpc/src/index.ts +76 -176
  61. package/templates/variants/bun-connectrpc/src/temporal/activities.ts +14 -0
  62. package/templates/variants/bun-connectrpc/src/temporal/worker.ts +38 -0
  63. package/templates/variants/bun-connectrpc/src/temporal/workflows.ts +10 -0
  64. package/templates/variants/bun-connectrpc/src/waitlist/service.ts +172 -0
  65. package/templates/variants/bun-connectrpc/src/waitlist/types.ts +45 -0
  66. package/templates/variants/bun-connectrpc/test/app.test.ts +4 -4
  67. package/templates/variants/bun-connectrpc/test/waitlist.integration.test.ts +71 -0
  68. package/templates/variants/bun-hono/Makefile +14 -8
  69. package/templates/variants/bun-hono/migrations/0000_init.sql +12 -55
  70. package/templates/variants/bun-hono/package.json +12 -5
  71. package/templates/variants/bun-hono/scripts/migrate.ts +4 -1
  72. package/templates/variants/bun-hono/src/auth.ts +181 -0
  73. package/templates/variants/bun-hono/src/db/repository.ts +68 -421
  74. package/templates/variants/bun-hono/src/db/schema.ts +15 -64
  75. package/templates/variants/bun-hono/src/index.ts +65 -180
  76. package/templates/variants/bun-hono/src/temporal/activities.ts +14 -0
  77. package/templates/variants/bun-hono/src/temporal/worker.ts +38 -0
  78. package/templates/variants/bun-hono/src/temporal/workflows.ts +10 -0
  79. package/templates/variants/bun-hono/src/waitlist/service.ts +166 -0
  80. package/templates/variants/bun-hono/src/waitlist/types.ts +50 -0
  81. package/templates/variants/bun-hono/test/app.test.ts +72 -41
  82. package/templates/variants/bun-hono/test/waitlist.integration.test.ts +102 -0
  83. package/templates/variants/go-chi/Makefile +27 -11
  84. package/templates/variants/go-chi/atlas.hcl +8 -0
  85. package/templates/variants/go-chi/cmd/server/main.go +21 -10
  86. package/templates/variants/go-chi/go.mod +1 -3
  87. package/templates/variants/go-chi/internal/app/service.go +202 -685
  88. package/templates/variants/go-chi/internal/auth/middleware.go +289 -0
  89. package/templates/variants/go-chi/internal/auth/middleware_test.go +38 -0
  90. package/templates/variants/go-chi/internal/config/config.go +27 -11
  91. package/templates/variants/go-chi/internal/httpapi/routes.go +78 -157
  92. package/templates/variants/go-chi/internal/httpapi/waitlist_integration_test.go +199 -0
  93. package/templates/variants/go-chi/internal/temporal/activities.go +27 -0
  94. package/templates/variants/go-chi/internal/temporal/worker.go +42 -0
  95. package/templates/variants/go-chi/internal/temporal/workflows.go +18 -0
  96. package/templates/variants/go-chi/migrations/0000_init.sql +12 -55
  97. package/templates/variants/go-chi/migrations/atlas.sum +2 -0
  98. package/templates/variants/go-chi/package.json +7 -1
  99. package/templates/variants/go-connectrpc/Makefile +26 -9
  100. package/templates/variants/go-connectrpc/atlas.hcl +8 -0
  101. package/templates/variants/go-connectrpc/buf.gen.yaml +2 -2
  102. package/templates/variants/go-connectrpc/cmd/server/main.go +23 -12
  103. package/templates/variants/go-connectrpc/gen/waitlist/v1/waitlist.pb.go +960 -0
  104. package/templates/variants/go-connectrpc/gen/waitlist/v1/waitlistv1connect/waitlist.connect.go +283 -0
  105. package/templates/variants/go-connectrpc/go.mod +1 -1
  106. package/templates/variants/go-connectrpc/internal/app/service.go +202 -685
  107. package/templates/variants/go-connectrpc/internal/auth/middleware.go +289 -0
  108. package/templates/variants/go-connectrpc/internal/auth/middleware_test.go +38 -0
  109. package/templates/variants/go-connectrpc/internal/config/config.go +27 -11
  110. package/templates/variants/go-connectrpc/internal/connectapi/handler.go +78 -201
  111. package/templates/variants/go-connectrpc/internal/connectapi/waitlist_integration_test.go +122 -0
  112. package/templates/variants/go-connectrpc/internal/httpapi/routes.go +147 -9
  113. package/templates/variants/go-connectrpc/internal/temporal/activities.go +27 -0
  114. package/templates/variants/go-connectrpc/internal/temporal/worker.go +42 -0
  115. package/templates/variants/go-connectrpc/internal/temporal/workflows.go +18 -0
  116. package/templates/variants/go-connectrpc/migrations/0000_init.sql +12 -55
  117. package/templates/variants/go-connectrpc/migrations/atlas.sum +2 -0
  118. package/templates/variants/go-connectrpc/package.json +7 -1
  119. package/templates/variants/go-connectrpc/protos/waitlist/v1/waitlist.proto +93 -0
  120. package/templates/root/.github/workflows/buf-publish.yml +0 -19
  121. package/templates/root/.github/workflows/ci.yml +0 -26
  122. package/templates/root/.github/workflows/deploy.yml +0 -22
  123. package/templates/root/Dockerfile +0 -23
  124. package/templates/root/README.md +0 -69
  125. package/templates/root/buf.gen.yaml +0 -10
  126. package/templates/root/buf.yaml +0 -9
  127. package/templates/root/cmd/server/main.go +0 -44
  128. package/templates/root/gen/dns/v1/dns.pb.go +0 -623
  129. package/templates/root/gen/dns/v1/dnsv1connect/dns.connect.go +0 -192
  130. package/templates/root/go.mod +0 -10
  131. package/templates/root/internal/app/service.go +0 -152
  132. package/templates/root/internal/app/token_source.go +0 -50
  133. package/templates/root/internal/cloudflare/client.go +0 -160
  134. package/templates/root/internal/config/config.go +0 -55
  135. package/templates/root/internal/connectapi/handler.go +0 -79
  136. package/templates/root/internal/httpapi/routes.go +0 -93
  137. package/templates/root/internal/vault/client.go +0 -148
  138. package/templates/root/package.json +0 -12
  139. package/templates/root/protos/dns/v1/dns.proto +0 -58
  140. package/templates/root/scripts/cloudrun/bootstrap.ts +0 -65
  141. package/templates/root/scripts/cloudrun/config.ts +0 -50
  142. package/templates/root/scripts/cloudrun/deploy.ts +0 -41
  143. package/templates/root/scripts/cloudrun/lib.ts +0 -244
  144. package/templates/root/service.yaml +0 -50
  145. package/templates/root/test/go.test.ts +0 -19
  146. package/templates/shared/scripts/cloudrun/integrations.ts +0 -111
  147. package/templates/variants/bun-connectrpc/gen/protos/chat/v1/chat_pb.ts +0 -1078
  148. package/templates/variants/bun-connectrpc/protos/chat/v1/chat.proto +0 -228
  149. package/templates/variants/bun-connectrpc/src/chat/service.ts +0 -384
  150. package/templates/variants/bun-connectrpc/src/chat/types.ts +0 -142
  151. package/templates/variants/bun-connectrpc/src/storage.ts +0 -72
  152. package/templates/variants/bun-connectrpc/src/webhooks.ts +0 -35
  153. package/templates/variants/bun-connectrpc/test/list-messages.integration.test.ts +0 -182
  154. package/templates/variants/bun-hono/src/chat/service.ts +0 -384
  155. package/templates/variants/bun-hono/src/chat/types.ts +0 -142
  156. package/templates/variants/bun-hono/src/storage.ts +0 -72
  157. package/templates/variants/bun-hono/src/webhooks.ts +0 -35
  158. package/templates/variants/bun-hono/test/list-messages.integration.test.ts +0 -256
  159. package/templates/variants/go-chi/buf.gen.yaml +0 -12
  160. package/templates/variants/go-chi/buf.yaml +0 -9
  161. package/templates/variants/go-chi/cmd/migrate/main.go +0 -101
  162. package/templates/variants/go-chi/internal/httpapi/list_messages_integration_test.go +0 -298
  163. package/templates/variants/go-chi/protos/chat/v1/chat.proto +0 -219
  164. package/templates/variants/go-connectrpc/cmd/migrate/main.go +0 -101
  165. package/templates/variants/go-connectrpc/gen/chat/v1/chat.pb.go +0 -2512
  166. package/templates/variants/go-connectrpc/gen/chat/v1/chatv1connect/chat.connect.go +0 -571
  167. package/templates/variants/go-connectrpc/internal/connectapi/list_messages_integration_test.go +0 -216
  168. package/templates/variants/go-connectrpc/protos/chat/v1/chat.proto +0 -232
@@ -1,9 +1,9 @@
1
- .PHONY: dev migrate gen lint test bootstrap deploy cleanup
1
+ .PHONY: dev migrate gen lint test create deploy dashboards auth destroy
2
2
 
3
- CLOUDRUN := npx --no-install svc-cloudrun
3
+ SERVICE := npx --no-install service
4
4
 
5
5
  dev:
6
- bun run ./src/index.ts
6
+ bun run dev
7
7
 
8
8
  migrate:
9
9
  bun run ./scripts/migrate.ts
@@ -17,11 +17,17 @@ lint:
17
17
  test:
18
18
  bun test
19
19
 
20
- bootstrap:
21
- $(CLOUDRUN) bootstrap
20
+ create:
21
+ $(SERVICE) create
22
22
 
23
23
  deploy:
24
- $(CLOUDRUN) deploy $(ARGS)
24
+ $(SERVICE) deploy $(ARGS)
25
25
 
26
- cleanup:
27
- $(CLOUDRUN) cleanup $(ARGS)
26
+ dashboards:
27
+ $(SERVICE) dashboards
28
+
29
+ auth:
30
+ $(SERVICE) auth $(ARGS)
31
+
32
+ destroy:
33
+ $(SERVICE) destroy $(ARGS)
@@ -0,0 +1,424 @@
1
+ // @generated by protoc-gen-es v2.12.0 with parameter "target=ts"
2
+ // @generated from file protos/waitlist/v1/waitlist.proto (package waitlist.v1, syntax proto3)
3
+ /* eslint-disable */
4
+
5
+ import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2";
6
+ import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2";
7
+ import type { Message } from "@bufbuild/protobuf";
8
+
9
+ /**
10
+ * Describes the file protos/waitlist/v1/waitlist.proto.
11
+ */
12
+ export const file_protos_waitlist_v1_waitlist: GenFile = /*@__PURE__*/
13
+ fileDesc("CiFwcm90b3Mvd2FpdGxpc3QvdjEvd2FpdGxpc3QucHJvdG8SC3dhaXRsaXN0LnYxIpEBCg1XYWl0bGlzdEVudHJ5EgoKAmlkGAEgASgJEg0KBWVtYWlsGAIgASgJEgwKBG5hbWUYAyABKAkSDwoHY29tcGFueRgEIAEoCRIOCgZzb3VyY2UYBSABKAkSDgoGc3RhdHVzGAYgASgJEhIKCmNyZWF0ZWRfYXQYByABKAkSEgoKdXBkYXRlZF9hdBgIIAEoCSKNAQoPV2FpdGxpc3RUcmlnZ2VyEgoKAmlkGAEgASgJEgwKBHR5cGUYAiABKAkSEAoIZW50cnlfaWQYAyABKAkSDgoGc3RhdHVzGAQgASgJEhQKDHBheWxvYWRfanNvbhgFIAEoCRISCgpjcmVhdGVkX2F0GAYgASgJEhQKDHByb2Nlc3NlZF9hdBgHIAEoCSJTChNKb2luV2FpdGxpc3RSZXF1ZXN0Eg0KBWVtYWlsGAEgASgJEgwKBG5hbWUYAiABKAkSDwoHY29tcGFueRgDIAEoCRIOCgZzb3VyY2UYBCABKAkiUgoUSm9pbldhaXRsaXN0UmVzcG9uc2USKQoFZW50cnkYASABKAsyGi53YWl0bGlzdC52MS5XYWl0bGlzdEVudHJ5Eg8KB2NyZWF0ZWQYAiABKAgiKwoXR2V0V2FpdGxpc3RFbnRyeVJlcXVlc3QSEAoIZW50cnlfaWQYASABKAkiLwoeR2V0V2FpdGxpc3RFbnRyeUJ5RW1haWxSZXF1ZXN0Eg0KBWVtYWlsGAEgASgJIkUKGEdldFdhaXRsaXN0RW50cnlSZXNwb25zZRIpCgVlbnRyeRgBIAEoCzIaLndhaXRsaXN0LnYxLldhaXRsaXN0RW50cnkiOwoaTGlzdFdhaXRsaXN0RW50cmllc1JlcXVlc3QSDgoGc3RhdHVzGAEgASgJEg0KBWxpbWl0GAIgASgNIkoKG0xpc3RXYWl0bGlzdEVudHJpZXNSZXNwb25zZRIrCgdlbnRyaWVzGAEgAygLMhoud2FpdGxpc3QudjEuV2FpdGxpc3RFbnRyeSI+ChpVcGRhdGVXYWl0bGlzdEVudHJ5UmVxdWVzdBIQCghlbnRyeV9pZBgBIAEoCRIOCgZzdGF0dXMYAiABKAkiPQocRXhwb3J0V2FpdGxpc3RFbnRyaWVzUmVxdWVzdBIOCgZzdGF0dXMYASABKAkSDQoFbGltaXQYAiABKA0iLAodRXhwb3J0V2FpdGxpc3RFbnRyaWVzUmVzcG9uc2USCwoDY3N2GAEgASgJIkwKFFJlY29yZFRyaWdnZXJSZXF1ZXN0EgwKBHR5cGUYASABKAkSEAoIZW50cnlfaWQYAiABKAkSFAoMcGF5bG9hZF9qc29uGAMgASgJIkYKFVJlY29yZFRyaWdnZXJSZXNwb25zZRItCgd0cmlnZ2VyGAEgASgLMhwud2FpdGxpc3QudjEuV2FpdGxpc3RUcmlnZ2VyMt0FCg9XYWl0bGlzdFNlcnZpY2USVQoMSm9pbldhaXRsaXN0EiAud2FpdGxpc3QudjEuSm9pbldhaXRsaXN0UmVxdWVzdBohLndhaXRsaXN0LnYxLkpvaW5XYWl0bGlzdFJlc3BvbnNlIgASYQoQR2V0V2FpdGxpc3RFbnRyeRIkLndhaXRsaXN0LnYxLkdldFdhaXRsaXN0RW50cnlSZXF1ZXN0GiUud2FpdGxpc3QudjEuR2V0V2FpdGxpc3RFbnRyeVJlc3BvbnNlIgASbwoXR2V0V2FpdGxpc3RFbnRyeUJ5RW1haWwSKy53YWl0bGlzdC52MS5HZXRXYWl0bGlzdEVudHJ5QnlFbWFpbFJlcXVlc3QaJS53YWl0bGlzdC52MS5HZXRXYWl0bGlzdEVudHJ5UmVzcG9uc2UiABJqChNMaXN0V2FpdGxpc3RFbnRyaWVzEicud2FpdGxpc3QudjEuTGlzdFdhaXRsaXN0RW50cmllc1JlcXVlc3QaKC53YWl0bGlzdC52MS5MaXN0V2FpdGxpc3RFbnRyaWVzUmVzcG9uc2UiABJnChNVcGRhdGVXYWl0bGlzdEVudHJ5Eicud2FpdGxpc3QudjEuVXBkYXRlV2FpdGxpc3RFbnRyeVJlcXVlc3QaJS53YWl0bGlzdC52MS5HZXRXYWl0bGlzdEVudHJ5UmVzcG9uc2UiABJwChVFeHBvcnRXYWl0bGlzdEVudHJpZXMSKS53YWl0bGlzdC52MS5FeHBvcnRXYWl0bGlzdEVudHJpZXNSZXF1ZXN0Gioud2FpdGxpc3QudjEuRXhwb3J0V2FpdGxpc3RFbnRyaWVzUmVzcG9uc2UiABJYCg1SZWNvcmRUcmlnZ2VyEiEud2FpdGxpc3QudjEuUmVjb3JkVHJpZ2dlclJlcXVlc3QaIi53YWl0bGlzdC52MS5SZWNvcmRUcmlnZ2VyUmVzcG9uc2UiAGIGcHJvdG8z");
14
+
15
+ /**
16
+ * @generated from message waitlist.v1.WaitlistEntry
17
+ */
18
+ export type WaitlistEntry = Message<"waitlist.v1.WaitlistEntry"> & {
19
+ /**
20
+ * @generated from field: string id = 1;
21
+ */
22
+ id: string;
23
+
24
+ /**
25
+ * @generated from field: string email = 2;
26
+ */
27
+ email: string;
28
+
29
+ /**
30
+ * @generated from field: string name = 3;
31
+ */
32
+ name: string;
33
+
34
+ /**
35
+ * @generated from field: string company = 4;
36
+ */
37
+ company: string;
38
+
39
+ /**
40
+ * @generated from field: string source = 5;
41
+ */
42
+ source: string;
43
+
44
+ /**
45
+ * @generated from field: string status = 6;
46
+ */
47
+ status: string;
48
+
49
+ /**
50
+ * @generated from field: string created_at = 7;
51
+ */
52
+ createdAt: string;
53
+
54
+ /**
55
+ * @generated from field: string updated_at = 8;
56
+ */
57
+ updatedAt: string;
58
+ };
59
+
60
+ /**
61
+ * Describes the message waitlist.v1.WaitlistEntry.
62
+ * Use `create(WaitlistEntrySchema)` to create a new message.
63
+ */
64
+ export const WaitlistEntrySchema: GenMessage<WaitlistEntry> = /*@__PURE__*/
65
+ messageDesc(file_protos_waitlist_v1_waitlist, 0);
66
+
67
+ /**
68
+ * @generated from message waitlist.v1.WaitlistTrigger
69
+ */
70
+ export type WaitlistTrigger = Message<"waitlist.v1.WaitlistTrigger"> & {
71
+ /**
72
+ * @generated from field: string id = 1;
73
+ */
74
+ id: string;
75
+
76
+ /**
77
+ * @generated from field: string type = 2;
78
+ */
79
+ type: string;
80
+
81
+ /**
82
+ * @generated from field: string entry_id = 3;
83
+ */
84
+ entryId: string;
85
+
86
+ /**
87
+ * @generated from field: string status = 4;
88
+ */
89
+ status: string;
90
+
91
+ /**
92
+ * @generated from field: string payload_json = 5;
93
+ */
94
+ payloadJson: string;
95
+
96
+ /**
97
+ * @generated from field: string created_at = 6;
98
+ */
99
+ createdAt: string;
100
+
101
+ /**
102
+ * @generated from field: string processed_at = 7;
103
+ */
104
+ processedAt: string;
105
+ };
106
+
107
+ /**
108
+ * Describes the message waitlist.v1.WaitlistTrigger.
109
+ * Use `create(WaitlistTriggerSchema)` to create a new message.
110
+ */
111
+ export const WaitlistTriggerSchema: GenMessage<WaitlistTrigger> = /*@__PURE__*/
112
+ messageDesc(file_protos_waitlist_v1_waitlist, 1);
113
+
114
+ /**
115
+ * @generated from message waitlist.v1.JoinWaitlistRequest
116
+ */
117
+ export type JoinWaitlistRequest = Message<"waitlist.v1.JoinWaitlistRequest"> & {
118
+ /**
119
+ * @generated from field: string email = 1;
120
+ */
121
+ email: string;
122
+
123
+ /**
124
+ * @generated from field: string name = 2;
125
+ */
126
+ name: string;
127
+
128
+ /**
129
+ * @generated from field: string company = 3;
130
+ */
131
+ company: string;
132
+
133
+ /**
134
+ * @generated from field: string source = 4;
135
+ */
136
+ source: string;
137
+ };
138
+
139
+ /**
140
+ * Describes the message waitlist.v1.JoinWaitlistRequest.
141
+ * Use `create(JoinWaitlistRequestSchema)` to create a new message.
142
+ */
143
+ export const JoinWaitlistRequestSchema: GenMessage<JoinWaitlistRequest> = /*@__PURE__*/
144
+ messageDesc(file_protos_waitlist_v1_waitlist, 2);
145
+
146
+ /**
147
+ * @generated from message waitlist.v1.JoinWaitlistResponse
148
+ */
149
+ export type JoinWaitlistResponse = Message<"waitlist.v1.JoinWaitlistResponse"> & {
150
+ /**
151
+ * @generated from field: waitlist.v1.WaitlistEntry entry = 1;
152
+ */
153
+ entry?: WaitlistEntry | undefined;
154
+
155
+ /**
156
+ * @generated from field: bool created = 2;
157
+ */
158
+ created: boolean;
159
+ };
160
+
161
+ /**
162
+ * Describes the message waitlist.v1.JoinWaitlistResponse.
163
+ * Use `create(JoinWaitlistResponseSchema)` to create a new message.
164
+ */
165
+ export const JoinWaitlistResponseSchema: GenMessage<JoinWaitlistResponse> = /*@__PURE__*/
166
+ messageDesc(file_protos_waitlist_v1_waitlist, 3);
167
+
168
+ /**
169
+ * @generated from message waitlist.v1.GetWaitlistEntryRequest
170
+ */
171
+ export type GetWaitlistEntryRequest = Message<"waitlist.v1.GetWaitlistEntryRequest"> & {
172
+ /**
173
+ * @generated from field: string entry_id = 1;
174
+ */
175
+ entryId: string;
176
+ };
177
+
178
+ /**
179
+ * Describes the message waitlist.v1.GetWaitlistEntryRequest.
180
+ * Use `create(GetWaitlistEntryRequestSchema)` to create a new message.
181
+ */
182
+ export const GetWaitlistEntryRequestSchema: GenMessage<GetWaitlistEntryRequest> = /*@__PURE__*/
183
+ messageDesc(file_protos_waitlist_v1_waitlist, 4);
184
+
185
+ /**
186
+ * @generated from message waitlist.v1.GetWaitlistEntryByEmailRequest
187
+ */
188
+ export type GetWaitlistEntryByEmailRequest = Message<"waitlist.v1.GetWaitlistEntryByEmailRequest"> & {
189
+ /**
190
+ * @generated from field: string email = 1;
191
+ */
192
+ email: string;
193
+ };
194
+
195
+ /**
196
+ * Describes the message waitlist.v1.GetWaitlistEntryByEmailRequest.
197
+ * Use `create(GetWaitlistEntryByEmailRequestSchema)` to create a new message.
198
+ */
199
+ export const GetWaitlistEntryByEmailRequestSchema: GenMessage<GetWaitlistEntryByEmailRequest> = /*@__PURE__*/
200
+ messageDesc(file_protos_waitlist_v1_waitlist, 5);
201
+
202
+ /**
203
+ * @generated from message waitlist.v1.GetWaitlistEntryResponse
204
+ */
205
+ export type GetWaitlistEntryResponse = Message<"waitlist.v1.GetWaitlistEntryResponse"> & {
206
+ /**
207
+ * @generated from field: waitlist.v1.WaitlistEntry entry = 1;
208
+ */
209
+ entry?: WaitlistEntry | undefined;
210
+ };
211
+
212
+ /**
213
+ * Describes the message waitlist.v1.GetWaitlistEntryResponse.
214
+ * Use `create(GetWaitlistEntryResponseSchema)` to create a new message.
215
+ */
216
+ export const GetWaitlistEntryResponseSchema: GenMessage<GetWaitlistEntryResponse> = /*@__PURE__*/
217
+ messageDesc(file_protos_waitlist_v1_waitlist, 6);
218
+
219
+ /**
220
+ * @generated from message waitlist.v1.ListWaitlistEntriesRequest
221
+ */
222
+ export type ListWaitlistEntriesRequest = Message<"waitlist.v1.ListWaitlistEntriesRequest"> & {
223
+ /**
224
+ * @generated from field: string status = 1;
225
+ */
226
+ status: string;
227
+
228
+ /**
229
+ * @generated from field: uint32 limit = 2;
230
+ */
231
+ limit: number;
232
+ };
233
+
234
+ /**
235
+ * Describes the message waitlist.v1.ListWaitlistEntriesRequest.
236
+ * Use `create(ListWaitlistEntriesRequestSchema)` to create a new message.
237
+ */
238
+ export const ListWaitlistEntriesRequestSchema: GenMessage<ListWaitlistEntriesRequest> = /*@__PURE__*/
239
+ messageDesc(file_protos_waitlist_v1_waitlist, 7);
240
+
241
+ /**
242
+ * @generated from message waitlist.v1.ListWaitlistEntriesResponse
243
+ */
244
+ export type ListWaitlistEntriesResponse = Message<"waitlist.v1.ListWaitlistEntriesResponse"> & {
245
+ /**
246
+ * @generated from field: repeated waitlist.v1.WaitlistEntry entries = 1;
247
+ */
248
+ entries: WaitlistEntry[];
249
+ };
250
+
251
+ /**
252
+ * Describes the message waitlist.v1.ListWaitlistEntriesResponse.
253
+ * Use `create(ListWaitlistEntriesResponseSchema)` to create a new message.
254
+ */
255
+ export const ListWaitlistEntriesResponseSchema: GenMessage<ListWaitlistEntriesResponse> = /*@__PURE__*/
256
+ messageDesc(file_protos_waitlist_v1_waitlist, 8);
257
+
258
+ /**
259
+ * @generated from message waitlist.v1.UpdateWaitlistEntryRequest
260
+ */
261
+ export type UpdateWaitlistEntryRequest = Message<"waitlist.v1.UpdateWaitlistEntryRequest"> & {
262
+ /**
263
+ * @generated from field: string entry_id = 1;
264
+ */
265
+ entryId: string;
266
+
267
+ /**
268
+ * @generated from field: string status = 2;
269
+ */
270
+ status: string;
271
+ };
272
+
273
+ /**
274
+ * Describes the message waitlist.v1.UpdateWaitlistEntryRequest.
275
+ * Use `create(UpdateWaitlistEntryRequestSchema)` to create a new message.
276
+ */
277
+ export const UpdateWaitlistEntryRequestSchema: GenMessage<UpdateWaitlistEntryRequest> = /*@__PURE__*/
278
+ messageDesc(file_protos_waitlist_v1_waitlist, 9);
279
+
280
+ /**
281
+ * @generated from message waitlist.v1.ExportWaitlistEntriesRequest
282
+ */
283
+ export type ExportWaitlistEntriesRequest = Message<"waitlist.v1.ExportWaitlistEntriesRequest"> & {
284
+ /**
285
+ * @generated from field: string status = 1;
286
+ */
287
+ status: string;
288
+
289
+ /**
290
+ * @generated from field: uint32 limit = 2;
291
+ */
292
+ limit: number;
293
+ };
294
+
295
+ /**
296
+ * Describes the message waitlist.v1.ExportWaitlistEntriesRequest.
297
+ * Use `create(ExportWaitlistEntriesRequestSchema)` to create a new message.
298
+ */
299
+ export const ExportWaitlistEntriesRequestSchema: GenMessage<ExportWaitlistEntriesRequest> = /*@__PURE__*/
300
+ messageDesc(file_protos_waitlist_v1_waitlist, 10);
301
+
302
+ /**
303
+ * @generated from message waitlist.v1.ExportWaitlistEntriesResponse
304
+ */
305
+ export type ExportWaitlistEntriesResponse = Message<"waitlist.v1.ExportWaitlistEntriesResponse"> & {
306
+ /**
307
+ * @generated from field: string csv = 1;
308
+ */
309
+ csv: string;
310
+ };
311
+
312
+ /**
313
+ * Describes the message waitlist.v1.ExportWaitlistEntriesResponse.
314
+ * Use `create(ExportWaitlistEntriesResponseSchema)` to create a new message.
315
+ */
316
+ export const ExportWaitlistEntriesResponseSchema: GenMessage<ExportWaitlistEntriesResponse> = /*@__PURE__*/
317
+ messageDesc(file_protos_waitlist_v1_waitlist, 11);
318
+
319
+ /**
320
+ * @generated from message waitlist.v1.RecordTriggerRequest
321
+ */
322
+ export type RecordTriggerRequest = Message<"waitlist.v1.RecordTriggerRequest"> & {
323
+ /**
324
+ * @generated from field: string type = 1;
325
+ */
326
+ type: string;
327
+
328
+ /**
329
+ * @generated from field: string entry_id = 2;
330
+ */
331
+ entryId: string;
332
+
333
+ /**
334
+ * @generated from field: string payload_json = 3;
335
+ */
336
+ payloadJson: string;
337
+ };
338
+
339
+ /**
340
+ * Describes the message waitlist.v1.RecordTriggerRequest.
341
+ * Use `create(RecordTriggerRequestSchema)` to create a new message.
342
+ */
343
+ export const RecordTriggerRequestSchema: GenMessage<RecordTriggerRequest> = /*@__PURE__*/
344
+ messageDesc(file_protos_waitlist_v1_waitlist, 12);
345
+
346
+ /**
347
+ * @generated from message waitlist.v1.RecordTriggerResponse
348
+ */
349
+ export type RecordTriggerResponse = Message<"waitlist.v1.RecordTriggerResponse"> & {
350
+ /**
351
+ * @generated from field: waitlist.v1.WaitlistTrigger trigger = 1;
352
+ */
353
+ trigger?: WaitlistTrigger | undefined;
354
+ };
355
+
356
+ /**
357
+ * Describes the message waitlist.v1.RecordTriggerResponse.
358
+ * Use `create(RecordTriggerResponseSchema)` to create a new message.
359
+ */
360
+ export const RecordTriggerResponseSchema: GenMessage<RecordTriggerResponse> = /*@__PURE__*/
361
+ messageDesc(file_protos_waitlist_v1_waitlist, 13);
362
+
363
+ /**
364
+ * @generated from service waitlist.v1.WaitlistService
365
+ */
366
+ export const WaitlistService: GenService<{
367
+ /**
368
+ * @generated from rpc waitlist.v1.WaitlistService.JoinWaitlist
369
+ */
370
+ joinWaitlist: {
371
+ methodKind: "unary";
372
+ input: typeof JoinWaitlistRequestSchema;
373
+ output: typeof JoinWaitlistResponseSchema;
374
+ },
375
+ /**
376
+ * @generated from rpc waitlist.v1.WaitlistService.GetWaitlistEntry
377
+ */
378
+ getWaitlistEntry: {
379
+ methodKind: "unary";
380
+ input: typeof GetWaitlistEntryRequestSchema;
381
+ output: typeof GetWaitlistEntryResponseSchema;
382
+ },
383
+ /**
384
+ * @generated from rpc waitlist.v1.WaitlistService.GetWaitlistEntryByEmail
385
+ */
386
+ getWaitlistEntryByEmail: {
387
+ methodKind: "unary";
388
+ input: typeof GetWaitlistEntryByEmailRequestSchema;
389
+ output: typeof GetWaitlistEntryResponseSchema;
390
+ },
391
+ /**
392
+ * @generated from rpc waitlist.v1.WaitlistService.ListWaitlistEntries
393
+ */
394
+ listWaitlistEntries: {
395
+ methodKind: "unary";
396
+ input: typeof ListWaitlistEntriesRequestSchema;
397
+ output: typeof ListWaitlistEntriesResponseSchema;
398
+ },
399
+ /**
400
+ * @generated from rpc waitlist.v1.WaitlistService.UpdateWaitlistEntry
401
+ */
402
+ updateWaitlistEntry: {
403
+ methodKind: "unary";
404
+ input: typeof UpdateWaitlistEntryRequestSchema;
405
+ output: typeof GetWaitlistEntryResponseSchema;
406
+ },
407
+ /**
408
+ * @generated from rpc waitlist.v1.WaitlistService.ExportWaitlistEntries
409
+ */
410
+ exportWaitlistEntries: {
411
+ methodKind: "unary";
412
+ input: typeof ExportWaitlistEntriesRequestSchema;
413
+ output: typeof ExportWaitlistEntriesResponseSchema;
414
+ },
415
+ /**
416
+ * @generated from rpc waitlist.v1.WaitlistService.RecordTrigger
417
+ */
418
+ recordTrigger: {
419
+ methodKind: "unary";
420
+ input: typeof RecordTriggerRequestSchema;
421
+ output: typeof RecordTriggerResponseSchema;
422
+ },
423
+ }> = /*@__PURE__*/
424
+ serviceDesc(file_protos_waitlist_v1_waitlist, 0);
@@ -1,63 +1,20 @@
1
- create table if not exists users (
1
+ create table if not exists waitlist_entries (
2
2
  id text primary key,
3
- username text not null unique,
4
- display_name text,
3
+ email text not null unique,
4
+ name text,
5
+ company text,
6
+ source text,
7
+ status text not null default 'joined',
5
8
  created_at timestamptz not null default now(),
6
9
  updated_at timestamptz not null default now()
7
10
  );
8
11
 
9
- create table if not exists conversations (
12
+ create table if not exists waitlist_triggers (
10
13
  id text primary key,
11
- title text,
12
- created_by_user_id text not null references users(id),
13
- deleted_at timestamptz,
14
- created_at timestamptz not null default now(),
15
- updated_at timestamptz not null default now()
16
- );
17
-
18
- create table if not exists conversation_participants (
19
- conversation_id text not null references conversations(id) on delete cascade,
20
- user_id text not null references users(id) on delete cascade,
21
- joined_at timestamptz not null default now(),
22
- primary key (conversation_id, user_id)
23
- );
24
-
25
- create table if not exists messages (
26
- id text primary key,
27
- conversation_id text not null references conversations(id) on delete cascade,
28
- user_id text not null references users(id),
29
- body text not null,
30
- edited_at timestamptz,
31
- deleted_at timestamptz,
32
- created_at timestamptz not null default now(),
33
- updated_at timestamptz not null default now()
34
- );
35
-
36
- create table if not exists attachments (
37
- id text primary key,
38
- conversation_id text not null references conversations(id) on delete cascade,
39
- message_id text references messages(id),
40
- uploaded_by_user_id text not null references users(id),
41
- storage_bucket text not null,
42
- storage_key text not null,
43
- content_type text not null,
44
- byte_size integer not null,
45
- filename text not null,
46
- status text not null,
47
- deleted_at timestamptz,
48
- created_at timestamptz not null default now(),
49
- updated_at timestamptz not null default now()
50
- );
51
-
52
- create table if not exists webhook_events (
53
- id text primary key,
54
- provider text not null,
55
- external_event_id text not null,
56
- event_type text not null,
57
- signature_valid text not null,
58
- status text not null,
14
+ type text not null,
15
+ entry_id text references waitlist_entries(id),
16
+ status text not null default 'queued',
59
17
  payload_json text not null,
60
- received_at timestamptz not null default now(),
61
- processed_at timestamptz,
62
- unique(provider, external_event_id)
18
+ created_at timestamptz not null default now(),
19
+ processed_at timestamptz
63
20
  );
@@ -3,24 +3,31 @@
3
3
  "private": true,
4
4
  "type": "module",
5
5
  "bin": {
6
- "svc-cloudrun": "./scripts/cloudrun/cli.ts"
6
+ "service": "./scripts/cloudrun/cli.ts"
7
7
  },
8
8
  "scripts": {
9
- "dev": "bun run ./src/index.ts",
9
+ "dev": "bun run ./scripts/dev.ts bun run ./src/index.ts",
10
+ "service": "bun run ./scripts/cloudrun/cli.ts",
10
11
  "migrate": "bun run ./scripts/migrate.ts",
11
12
  "gen": "bun run ./scripts/codegen.ts",
12
13
  "lint": "bunx tsc --noEmit",
13
14
  "test": "bun test",
14
- "bootstrap": "bun run ./scripts/cloudrun/cli.ts bootstrap",
15
+ "create": "bun run ./scripts/cloudrun/cli.ts create",
15
16
  "deploy": "bun run ./scripts/cloudrun/cli.ts deploy",
16
- "cleanup": "bun run ./scripts/cloudrun/cli.ts cleanup"
17
+ "dashboards": "bun run ./scripts/cloudrun/cli.ts dashboards",
18
+ "auth": "bun run ./scripts/cloudrun/cli.ts auth",
19
+ "destroy": "bun run ./scripts/cloudrun/cli.ts destroy"
17
20
  },
18
21
  "dependencies": {
19
- "@google-cloud/storage": "^7.17.2",
22
+ "@anmho/authctl": "0.1.1",
20
23
  "@bufbuild/protobuf": "^2.7.0",
21
24
  "@clack/prompts": "^1.2.0",
22
25
  "@connectrpc/connect": "^2.0.2",
23
26
  "@connectrpc/connect-node": "^2.0.2",
27
+ "@temporalio/activity": "1.17.1",
28
+ "@temporalio/client": "1.17.1",
29
+ "@temporalio/worker": "1.17.1",
30
+ "@temporalio/workflow": "1.17.1",
24
31
  "drizzle-orm": "^0.44.5",
25
32
  "@neondatabase/api-client": "^2.7.1"
26
33
  },
@@ -0,0 +1,91 @@
1
+ syntax = "proto3";
2
+
3
+ package waitlist.v1;
4
+
5
+ service WaitlistService {
6
+ rpc JoinWaitlist(JoinWaitlistRequest) returns (JoinWaitlistResponse) {}
7
+ rpc GetWaitlistEntry(GetWaitlistEntryRequest) returns (GetWaitlistEntryResponse) {}
8
+ rpc GetWaitlistEntryByEmail(GetWaitlistEntryByEmailRequest) returns (GetWaitlistEntryResponse) {}
9
+ rpc ListWaitlistEntries(ListWaitlistEntriesRequest) returns (ListWaitlistEntriesResponse) {}
10
+ rpc UpdateWaitlistEntry(UpdateWaitlistEntryRequest) returns (GetWaitlistEntryResponse) {}
11
+ rpc ExportWaitlistEntries(ExportWaitlistEntriesRequest) returns (ExportWaitlistEntriesResponse) {}
12
+ rpc RecordTrigger(RecordTriggerRequest) returns (RecordTriggerResponse) {}
13
+ }
14
+
15
+ message WaitlistEntry {
16
+ string id = 1;
17
+ string email = 2;
18
+ string name = 3;
19
+ string company = 4;
20
+ string source = 5;
21
+ string status = 6;
22
+ string created_at = 7;
23
+ string updated_at = 8;
24
+ }
25
+
26
+ message WaitlistTrigger {
27
+ string id = 1;
28
+ string type = 2;
29
+ string entry_id = 3;
30
+ string status = 4;
31
+ string payload_json = 5;
32
+ string created_at = 6;
33
+ string processed_at = 7;
34
+ }
35
+
36
+ message JoinWaitlistRequest {
37
+ string email = 1;
38
+ string name = 2;
39
+ string company = 3;
40
+ string source = 4;
41
+ }
42
+
43
+ message JoinWaitlistResponse {
44
+ WaitlistEntry entry = 1;
45
+ bool created = 2;
46
+ }
47
+
48
+ message GetWaitlistEntryRequest {
49
+ string entry_id = 1;
50
+ }
51
+
52
+ message GetWaitlistEntryByEmailRequest {
53
+ string email = 1;
54
+ }
55
+
56
+ message GetWaitlistEntryResponse {
57
+ WaitlistEntry entry = 1;
58
+ }
59
+
60
+ message ListWaitlistEntriesRequest {
61
+ string status = 1;
62
+ uint32 limit = 2;
63
+ }
64
+
65
+ message ListWaitlistEntriesResponse {
66
+ repeated WaitlistEntry entries = 1;
67
+ }
68
+
69
+ message UpdateWaitlistEntryRequest {
70
+ string entry_id = 1;
71
+ string status = 2;
72
+ }
73
+
74
+ message ExportWaitlistEntriesRequest {
75
+ string status = 1;
76
+ uint32 limit = 2;
77
+ }
78
+
79
+ message ExportWaitlistEntriesResponse {
80
+ string csv = 1;
81
+ }
82
+
83
+ message RecordTriggerRequest {
84
+ string type = 1;
85
+ string entry_id = 2;
86
+ string payload_json = 3;
87
+ }
88
+
89
+ message RecordTriggerResponse {
90
+ WaitlistTrigger trigger = 1;
91
+ }
@@ -16,7 +16,7 @@ const result = Bun.spawnSync(
16
16
  `--plugin=protoc-gen-es=${plugin}`,
17
17
  "--es_out=gen",
18
18
  "--es_opt=target=ts",
19
- "protos/chat/v1/chat.proto",
19
+ "protos/waitlist/v1/waitlist.proto",
20
20
  ],
21
21
  {
22
22
  cwd: process.cwd(),
@@ -1,4 +1,7 @@
1
1
  import { SQL } from "bun";
2
+ import { ensureLocalPostgres } from "./local-docker";
3
+
4
+ await ensureLocalPostgres();
2
5
 
3
6
  const databaseUrl = Bun.env.DATABASE_URL?.trim();
4
7
  if (!databaseUrl) {
@@ -7,7 +10,7 @@ if (!databaseUrl) {
7
10
 
8
11
  const client = new SQL(databaseUrl);
9
12
  await waitForDatabase(client);
10
- const migrationId = "0000_init_chat";
13
+ const migrationId = "0000_init_waitlist";
11
14
  const migrationSql = await Bun.file(new URL("../migrations/0000_init.sql", import.meta.url)).text();
12
15
 
13
16
  await client.unsafe(`create table if not exists schema_migrations (