@vestcards/server-types 1.3.0 → 1.5.0

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 (94) hide show
  1. package/dist/apps/server/src/app.d.ts +382 -20
  2. package/dist/apps/server/src/config/env.d.ts +9 -1
  3. package/dist/apps/server/src/lib/metrics.d.ts +4 -0
  4. package/dist/apps/server/src/lib/posthog.d.ts +2 -0
  5. package/dist/apps/server/src/middleware/errorHandler.d.ts +1 -1
  6. package/dist/apps/server/src/middleware/logger.d.ts +14 -29
  7. package/dist/apps/server/src/middleware/logger.test.d.ts +1 -0
  8. package/dist/apps/server/src/modules/auth/index.d.ts +4 -4
  9. package/dist/apps/server/src/modules/auth/lib.d.ts +30 -3
  10. package/dist/apps/server/src/modules/auth/profile.d.ts +5 -0
  11. package/dist/apps/server/src/modules/auth/tracing.d.ts +18 -0
  12. package/dist/apps/server/src/modules/auth/tracing.test.d.ts +1 -0
  13. package/dist/apps/server/src/modules/auth/utils.d.ts +1 -0
  14. package/dist/apps/server/src/modules/card/index.d.ts +4 -4
  15. package/dist/apps/server/src/modules/cron/cron.test.d.ts +1 -0
  16. package/dist/apps/server/src/modules/cron/index.d.ts +53 -0
  17. package/dist/apps/server/src/modules/cron/jobs/expire-memberships.d.ts +1 -0
  18. package/dist/apps/server/src/modules/cron/jobs/payment-expiry-reminder.d.ts +1 -0
  19. package/dist/apps/server/src/modules/deck/access.d.ts +5 -0
  20. package/dist/apps/server/src/modules/deck/index.d.ts +23 -5
  21. package/dist/apps/server/src/modules/deck/model.d.ts +4 -0
  22. package/dist/apps/server/src/modules/deck/service.d.ts +5 -1
  23. package/dist/apps/server/src/modules/exam/exam.test.d.ts +1 -0
  24. package/dist/apps/server/src/modules/exam/index.d.ts +457 -0
  25. package/dist/apps/server/src/modules/exam/model.d.ts +18 -0
  26. package/dist/apps/server/src/modules/exam/service.d.ts +43 -0
  27. package/dist/apps/server/src/modules/library/index.d.ts +4 -4
  28. package/dist/apps/server/src/modules/ranking/cache.d.ts +6 -0
  29. package/dist/apps/server/src/modules/ranking/helpers.d.ts +9 -0
  30. package/dist/apps/server/src/modules/ranking/index.d.ts +412 -0
  31. package/dist/apps/server/src/modules/ranking/model.d.ts +28 -0
  32. package/dist/apps/server/src/modules/ranking/ranking.test.d.ts +1 -0
  33. package/dist/apps/server/src/modules/ranking/repository.d.ts +10 -0
  34. package/dist/apps/server/src/modules/ranking/service.d.ts +4 -0
  35. package/dist/apps/server/src/modules/stats/index.d.ts +446 -0
  36. package/dist/apps/server/src/modules/stats/model.d.ts +85 -0
  37. package/dist/apps/server/src/modules/stats/service.d.ts +27 -0
  38. package/dist/apps/server/src/modules/stats/stats.test.d.ts +1 -0
  39. package/dist/apps/server/src/modules/study/index.d.ts +4 -4
  40. package/dist/apps/server/src/modules/study/service.d.ts +4 -4
  41. package/dist/apps/server/src/modules/topic/index.d.ts +4 -4
  42. package/dist/apps/server/src/modules/user/index.d.ts +36 -19
  43. package/dist/apps/server/src/modules/user/model.d.ts +11 -1
  44. package/dist/apps/server/src/modules/user/service.d.ts +13 -29
  45. package/dist/apps/server/src/modules/vesty/index.d.ts +473 -0
  46. package/dist/apps/server/src/modules/vesty/model.d.ts +35 -0
  47. package/dist/apps/server/src/modules/vesty/resilience.d.ts +40 -0
  48. package/dist/apps/server/src/modules/vesty/resilience.test.d.ts +1 -0
  49. package/dist/apps/server/src/modules/vesty/service.d.ts +6 -0
  50. package/dist/apps/server/src/modules/vesty/services/generate-deck.d.ts +2 -0
  51. package/dist/apps/server/src/modules/vesty/services/insights.d.ts +3 -0
  52. package/dist/apps/server/src/modules/vesty/tools.d.ts +11 -0
  53. package/dist/apps/server/src/modules/vesty/utils.d.ts +62 -0
  54. package/dist/apps/server/src/modules/vesty/vesty.test.d.ts +1 -0
  55. package/dist/apps/server/src/server.d.ts +1 -0
  56. package/dist/apps/server/src/tests/helpers/fixtures.d.ts +8 -6
  57. package/dist/apps/server/src/tests/helpers/index.d.ts +1 -0
  58. package/dist/apps/server/src/tests/helpers/redis-mock.d.ts +33 -0
  59. package/dist/apps/server/src/tests/preload/redis-mock.d.ts +1 -0
  60. package/dist/apps/server/src/tests/preload/vesty-mock.d.ts +1 -0
  61. package/dist/packages/db-core/src/db.d.ts +1 -2
  62. package/dist/packages/db-core/src/index.d.ts +1 -1
  63. package/dist/packages/db-core/src/queries/decks.d.ts +2 -0
  64. package/dist/packages/db-core/src/queries/index.d.ts +1 -0
  65. package/dist/packages/db-core/src/schema/auth.d.ts +34 -0
  66. package/dist/packages/db-core/src/schema/exams.d.ts +721 -0
  67. package/dist/packages/db-core/src/schema/index.d.ts +1 -1
  68. package/dist/packages/db-core/src/schema/payment.d.ts +37 -1
  69. package/dist/packages/db-core/src/tracing.d.ts +2 -0
  70. package/dist/packages/email-core/src/templates/index.d.ts +2 -0
  71. package/dist/packages/email-core/src/templates/paymentExpiryReminder.d.ts +9 -0
  72. package/dist/packages/shared/src/constants.d.ts +2 -0
  73. package/dist/packages/shared/src/date/index.d.ts +1 -0
  74. package/dist/packages/shared/src/date/timezone.d.ts +29 -0
  75. package/dist/packages/shared/src/index.d.ts +1 -0
  76. package/dist/packages/shared/src/spaced-repetition/config.d.ts +17 -2
  77. package/dist/packages/shared/src/spaced-repetition/index.d.ts +1 -0
  78. package/dist/packages/shared/src/spaced-repetition/retention.d.ts +2 -0
  79. package/dist/packages/shared/src/spaced-repetition/session-manager.d.ts +3 -0
  80. package/dist/packages/shared/src/theme/tokens/colors.d.ts +27 -27
  81. package/dist/packages/shared/src/types/index.d.ts +1 -0
  82. package/dist/packages/shared/src/types/permissions.d.ts +6 -0
  83. package/dist/packages/shared/src/types/user.d.ts +20 -0
  84. package/dist/packages/shared/src/types/vesty.d.ts +7 -0
  85. package/dist/packages/utils/src/logger/config.d.ts +12 -0
  86. package/dist/packages/utils/src/logger/index.d.ts +5 -1
  87. package/dist/packages/utils/src/logger/pino.d.ts +7 -0
  88. package/dist/packages/utils/src/logger/posthog.d.ts +16 -0
  89. package/dist/packages/utils/src/logger/timeout.d.ts +4 -0
  90. package/dist/packages/utils/src/logger/tracing.d.ts +34 -0
  91. package/package.json +1 -1
  92. package/dist/apps/server/src/modules/study/constants.d.ts +0 -5
  93. package/dist/packages/db-core/src/views/deck.d.ts +0 -79
  94. /package/dist/apps/server/src/{libs → lib}/mappers.d.ts +0 -0
@@ -0,0 +1,35 @@
1
+ export declare namespace VestyModel {
2
+ const chatBody: import("@sinclair/typebox").TObject<{
3
+ messages: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
4
+ role: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"user">, import("@sinclair/typebox").TLiteral<"assistant">]>;
5
+ parts: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TAny>;
6
+ }>>;
7
+ data: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TAny>>;
8
+ }>;
9
+ type ChatBody = typeof chatBody.static;
10
+ const generateDeckBody: import("@sinclair/typebox").TObject<{
11
+ prompt: import("@sinclair/typebox").TString;
12
+ }>;
13
+ type GenerateDeckBody = typeof generateDeckBody.static;
14
+ type GeneratedDeck = {
15
+ title: string;
16
+ description: string;
17
+ subject: string | null;
18
+ topicId: string | null;
19
+ cards: Array<{
20
+ question: string;
21
+ answer: string;
22
+ }>;
23
+ };
24
+ type InsightsResult = {
25
+ insights: Array<{
26
+ title: string;
27
+ description: string;
28
+ tag: string;
29
+ }>;
30
+ };
31
+ function toModelMessages(messages: ChatBody['messages']): {
32
+ role: 'user' | 'assistant';
33
+ content: string;
34
+ }[];
35
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Heuristically decides whether a Gemini provider error is transient and worth
3
+ * retrying (overload, rate limit, timeout) versus a permanent failure (bad
4
+ * request, schema mismatch) that a retry or different model won't fix.
5
+ */
6
+ export declare function isRetryableGeminiError(error: unknown): boolean;
7
+ type RetryConfig = {
8
+ attemptsPerModel: number;
9
+ baseDelayMs: number;
10
+ maxDelayMs: number;
11
+ };
12
+ export type FallbackOptions<TModel extends string = string> = Partial<RetryConfig> & {
13
+ /** Invoked before a backoff wait or a fallback to the next model. */
14
+ onRetry?: (info: {
15
+ model: TModel;
16
+ attempt: number;
17
+ error: unknown;
18
+ nextModel?: TModel;
19
+ }) => void;
20
+ };
21
+ /**
22
+ * Runs `run` against each model in order. Retries the same model with backoff
23
+ * on transient errors, then falls back to the next model, and finally rethrows
24
+ * the last error if every model is exhausted. Non-retryable errors short-circuit
25
+ * immediately. Returns the result together with the model that produced it.
26
+ */
27
+ export declare function runWithModelFallback<TModel extends string, TResult>(models: readonly TModel[], run: (model: TModel) => Promise<TResult>, options?: FallbackOptions<TModel>): Promise<{
28
+ result: TResult;
29
+ model: TModel;
30
+ }>;
31
+ /**
32
+ * Streaming counterpart of {@link runWithModelFallback}. Wraps an
33
+ * `AsyncIterable` source and retries / falls back to the next model — but only
34
+ * while no chunk has been emitted yet, since a stream cannot be safely restarted
35
+ * once the client has started receiving content. A `503` overload surfaces at
36
+ * connection time (before the first chunk), which is exactly the case this
37
+ * covers.
38
+ */
39
+ export declare function streamWithModelFallback<TModel extends string, TChunk>(models: readonly TModel[], createStream: (model: TModel) => AsyncIterable<TChunk>, options?: FallbackOptions<TModel>): AsyncIterable<TChunk>;
40
+ export {};
@@ -0,0 +1,6 @@
1
+ import { VestyModel } from './model';
2
+ export declare abstract class VestyService {
3
+ static generateDeck(prompt: string, userId: string): Promise<VestyModel.GeneratedDeck>;
4
+ static generateInsights(userId: string): Promise<VestyModel.InsightsResult>;
5
+ static createChatStream(messages: VestyModel.ChatBody['messages'], userName: string, userId: string): Promise<Response>;
6
+ }
@@ -0,0 +1,2 @@
1
+ import type { VestyModel } from '../model';
2
+ export declare function executeGenerateDeck(prompt: string, userId: string): Promise<VestyModel.GeneratedDeck>;
@@ -0,0 +1,3 @@
1
+ import type { VestyModel } from '../model';
2
+ export declare const DEFAULT_INSIGHTS_QUANTITY = 5;
3
+ export declare function executeGenerateInsights(userId: string, quantity: number): Promise<VestyModel.InsightsResult>;
@@ -0,0 +1,11 @@
1
+ import z from 'zod';
2
+ export declare const searchDecksTool: import("@tanstack/ai").ServerTool<z.ZodObject<{
3
+ query: z.ZodString;
4
+ }, z.core.$strip>, z.ZodObject<{
5
+ relatedDecks: z.ZodArray<z.ZodObject<{
6
+ id: z.ZodString;
7
+ title: z.ZodString;
8
+ subject: z.ZodString;
9
+ topicName: z.ZodString;
10
+ }, z.core.$strip>>;
11
+ }, z.core.$strip>, "buscar_decks">;
@@ -0,0 +1,62 @@
1
+ import type { ChatMiddleware, JSONSchema } from '@tanstack/ai';
2
+ import { GeminiTextAdapter, type GeminiTextModel } from '@tanstack/ai-gemini';
3
+ import type { Subject } from '@vestcards/shared';
4
+ import type { VestyModel } from './model';
5
+ export declare const VESTY_PRIMARY_MODEL: "gemini-3.1-pro-preview" | "gemini-3-pro-preview" | "gemini-3-flash-preview" | "gemini-3.1-flash-lite-preview" | "gemini-2.5-pro" | "gemini-2.5-flash" | "gemini-2.5-flash-preview-09-2025" | "gemini-2.5-flash-lite" | "gemini-2.5-flash-lite-preview-09-2025" | "gemini-2.0-flash" | "gemini-2.0-flash-lite";
6
+ export declare const VESTY_FALLBACK_MODEL: "gemini-3.1-pro-preview" | "gemini-3-pro-preview" | "gemini-3-flash-preview" | "gemini-3.1-flash-lite-preview" | "gemini-2.5-pro" | "gemini-2.5-flash" | "gemini-2.5-flash-preview-09-2025" | "gemini-2.5-flash-lite" | "gemini-2.5-flash-lite-preview-09-2025" | "gemini-2.0-flash" | "gemini-2.0-flash-lite";
7
+ export declare const VESTY_MODELS: readonly GeminiTextModel[];
8
+ export declare function getGeminiAdapter(model: GeminiTextModel): GeminiTextAdapter<GeminiTextModel>;
9
+ export declare const VESTY_SYSTEM_PROMPT: (userName: string) => string;
10
+ export declare const SUBJECT_DETECTION_SCHEMA: JSONSchema;
11
+ export declare const SUBJECT_DETECTION_PROMPT: string;
12
+ export declare const GeminiModelOptions: {
13
+ thinkingConfig: {
14
+ includeThoughts: boolean;
15
+ thinkingBudget: number;
16
+ };
17
+ };
18
+ export declare const GENERATE_DECK_SYSTEM_PROMPT: (topics: Array<{
19
+ id: string;
20
+ name: string;
21
+ }>) => string;
22
+ export declare const GENERATED_DECK_OUTPUT_SCHEMA: JSONSchema;
23
+ type DeckTopic = {
24
+ id: string;
25
+ name: string;
26
+ };
27
+ export declare function detectDeckSubject(model: GeminiTextModel, input: Array<{
28
+ role: 'user';
29
+ content: string;
30
+ }>): Promise<Subject | null>;
31
+ export declare function fetchDeckTopics(subject: Subject | null): Promise<DeckTopic[]>;
32
+ export declare function generateDeckFromPrompt(model: GeminiTextModel, input: Array<{
33
+ role: 'user';
34
+ content: string;
35
+ }>, topicList: DeckTopic[], subject: Subject | null): Promise<VestyModel.GeneratedDeck>;
36
+ export declare function captureAiGeneration(userId: string, props: {
37
+ traceId: string;
38
+ model: string;
39
+ input: {
40
+ role: string;
41
+ content: string;
42
+ }[];
43
+ latency: number;
44
+ stream: boolean;
45
+ isError: false;
46
+ } | {
47
+ traceId: string;
48
+ model: string;
49
+ input: {
50
+ role: string;
51
+ content: string;
52
+ }[];
53
+ latency: number;
54
+ stream: boolean;
55
+ isError: true;
56
+ error: string;
57
+ }): void;
58
+ export declare function createAnalyticsMiddleware(userId: string, inputMessages: {
59
+ role: 'user' | 'assistant';
60
+ content: string;
61
+ }[], traceId: string, model: string): ChatMiddleware;
62
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1,2 @@
1
+ import './modules/cron';
1
2
  import './config/env';
@@ -1,4 +1,4 @@
1
- import { MembershipStatus } from '@vestcards/shared';
1
+ import { type BillingType, type DeckStatus, MembershipStatus } from '@vestcards/shared';
2
2
  /**
3
3
  * Create a test topic
4
4
  */
@@ -22,10 +22,10 @@ export declare function createDeck(data: {
22
22
  ownerId: string;
23
23
  lastEditedBy?: string;
24
24
  free?: boolean;
25
- status?: string;
25
+ status?: DeckStatus;
26
26
  keywords?: string[];
27
27
  }): Promise<{
28
- status: import("@vestcards/shared").DeckStatus;
28
+ status: DeckStatus;
29
29
  id: string;
30
30
  createdAt: Date;
31
31
  updatedAt: Date;
@@ -82,7 +82,7 @@ export declare function createTestDeck(data: {
82
82
  answer: string | null;
83
83
  extend: unknown;
84
84
  }[];
85
- status: import("@vestcards/shared").DeckStatus;
85
+ status: DeckStatus;
86
86
  id: string;
87
87
  createdAt: Date;
88
88
  updatedAt: Date;
@@ -166,11 +166,13 @@ export declare function deleteOfficialEntity(entityId: string): Promise<void>;
166
166
  export declare function createMembership(data: {
167
167
  entityId: string;
168
168
  status?: MembershipStatus;
169
+ billingType?: BillingType;
169
170
  startedAt?: Date;
170
171
  expiresAt?: Date;
172
+ createdAt?: Date;
171
173
  }): Promise<{
172
- status: MembershipStatus;
173
174
  value: number;
175
+ status: MembershipStatus;
174
176
  id: string;
175
177
  entityId: string;
176
178
  createdAt: Date;
@@ -180,7 +182,7 @@ export declare function createMembership(data: {
180
182
  asaasPaymentId: string;
181
183
  asaasInstallmentId: string | null;
182
184
  installmentCount: number;
183
- billingType: import("@vestcards/shared").BillingType;
185
+ billingType: BillingType;
184
186
  couponCode: string | null;
185
187
  idempotencyKey: string | null;
186
188
  startedAt: Date | null;
@@ -1,3 +1,4 @@
1
1
  export * from './auth-helpers';
2
2
  export * from './fixtures';
3
3
  export * from './http-helpers';
4
+ export * from './redis-mock';
@@ -0,0 +1,33 @@
1
+ interface RedisSetOptions {
2
+ ex?: number;
3
+ }
4
+ interface RedisSetCall {
5
+ key: string;
6
+ value: unknown;
7
+ options?: RedisSetOptions;
8
+ }
9
+ declare class TestRedis {
10
+ private store;
11
+ private readError;
12
+ private writeError;
13
+ readonly getCalls: string[];
14
+ readonly setCalls: RedisSetCall[];
15
+ readonly delCalls: string[];
16
+ readonly client: {
17
+ get: (key: string) => Promise<unknown>;
18
+ set: (key: string, value: unknown, options?: RedisSetOptions) => Promise<string>;
19
+ del: (key: string) => Promise<number>;
20
+ };
21
+ seed(key: string, value: unknown): void;
22
+ read(key: string): unknown;
23
+ failReads(error?: Error): void;
24
+ failWrites(error?: Error): void;
25
+ clearFailures(): void;
26
+ clearCalls(): void;
27
+ reset(): void;
28
+ private get;
29
+ private set;
30
+ private del;
31
+ }
32
+ export declare const testRedis: TestRedis;
33
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,3 @@
1
- import { Pool } from 'pg';
2
1
  export declare const db: import("drizzle-orm/node-postgres").NodePgDatabase<Record<string, never>> & {
3
- $client: Pool;
2
+ $client: import("pg").Pool;
4
3
  };
@@ -1,4 +1,4 @@
1
1
  export { db } from './db';
2
+ export * from './queries';
2
3
  export * from './schema';
3
4
  export * from './utils';
4
- export * from './views/deck';
@@ -0,0 +1,2 @@
1
+ export declare const isOfficialDeckFilterQuery: () => import("drizzle-orm").SQL<unknown>;
2
+ export declare const deckOwnerFilterQuery: (ownerId: string) => import("drizzle-orm").SQL<unknown>;
@@ -0,0 +1 @@
1
+ export * from './decks';
@@ -825,6 +825,23 @@ export declare const userSettings: import("drizzle-orm/pg-core").PgTableWithColu
825
825
  identity: undefined;
826
826
  generated: undefined;
827
827
  }, {}, {}>;
828
+ timezone: import("drizzle-orm/pg-core").PgColumn<{
829
+ name: "timezone";
830
+ tableName: "user_settings";
831
+ dataType: "string";
832
+ columnType: "PgText";
833
+ data: string;
834
+ driverParam: string;
835
+ notNull: true;
836
+ hasDefault: true;
837
+ isPrimaryKey: false;
838
+ isAutoincrement: false;
839
+ hasRuntimeDefault: false;
840
+ enumValues: [string, ...string[]];
841
+ baseColumn: never;
842
+ identity: undefined;
843
+ generated: undefined;
844
+ }, {}, {}>;
828
845
  university: import("drizzle-orm/pg-core").PgColumn<{
829
846
  name: "university";
830
847
  tableName: "user_settings";
@@ -876,6 +893,23 @@ export declare const userSettings: import("drizzle-orm/pg-core").PgTableWithColu
876
893
  identity: undefined;
877
894
  generated: undefined;
878
895
  }, {}, {}>;
896
+ newCardsPerDeckDailyLimit: import("drizzle-orm/pg-core").PgColumn<{
897
+ name: "new_cards_per_deck_daily_limit";
898
+ tableName: "user_settings";
899
+ dataType: "number";
900
+ columnType: "PgInteger";
901
+ data: number;
902
+ driverParam: string | number;
903
+ notNull: false;
904
+ hasDefault: false;
905
+ isPrimaryKey: false;
906
+ isAutoincrement: false;
907
+ hasRuntimeDefault: false;
908
+ enumValues: undefined;
909
+ baseColumn: never;
910
+ identity: undefined;
911
+ generated: undefined;
912
+ }, {}, {}>;
879
913
  createdAt: import("drizzle-orm/pg-core").PgColumn<{
880
914
  name: "created_at";
881
915
  tableName: "user_settings";