@jobsearch-works/firestore-models 1.1.8 → 1.1.10

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,5 +1,8 @@
1
1
  # firestore-models
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@jobsearch-works/firestore-models.svg?style=flat-square)](https://www.npmjs.com/package/@jobsearch-works/firestore-models)
4
+ [![license](https://img.shields.io/npm/l/@jobsearch-works/firestore-models.svg?style=flat-square)](./LICENSE)
5
+
3
6
  A shared library for standardizing Firestore document schemas and paths across multiple projects.
4
7
 
5
8
  This library provides:
@@ -34,6 +37,17 @@ This package acts as a single source of truth for Firestore schema and paths, en
34
37
  - Consistent Firestore path generation (no hardcoded strings)
35
38
  - Cross-environment compatibility (e.g., CLI, testing, rules)
36
39
 
40
+ This package provides no Firestore SDK bindings. Firestore `DocumentReference`s and `CollectionReference`s are constructed in your application using these path strings, typically in a `firestoreRefs.ts` file like:
41
+
42
+ ```ts
43
+ import { doc, collection } from "firebase/firestore";
44
+ import { firestore } from "./firebaseConfig";
45
+ import { firestorePaths } from "@jobsearch-works/firestore-models";
46
+
47
+ export const userRef = (userId: string) =>
48
+ doc(firestore, firestorePaths.users.doc(userId));
49
+ ```
50
+
37
51
  ---
38
52
 
39
53
  ## 🧱 Project Structure
@@ -50,32 +64,416 @@ firestore-models/
50
64
 
51
65
  ---
52
66
 
67
+ ## 🔗 Entity Relationships
68
+
69
+ The following diagram and table illustrate how the main Firestore models relate to each other, both by reference (IDs) and by Firestore subcollections/paths:
70
+
71
+ ```
72
+ Client
73
+ ├── applications (Application)
74
+ │ └── questions (ApplicationQuestion)
75
+ ├── questions (ClientQuestion)
76
+ ├── preferences/targetPreferences (TargetPreferences)
77
+ ├── vacancySuggestions (VacancySuggestion)
78
+ └── clientEmails/{clientId}/messages (GmailMessage)
79
+
80
+ Vacancy
81
+ └── Referenced by Application and VacancySuggestion
82
+
83
+ Agent
84
+ └── Root collection
85
+
86
+ User
87
+ └── Root collection
88
+
89
+ ClientData
90
+ └── Root collection
91
+
92
+ ClientLogin
93
+ └── clientLogins/{userId}/logins/{domain}
94
+ ```
95
+
96
+ | Entity | References / Path | Description |
97
+ | ------------------- | ---------------------------------------------------- | -------------------------------------------------------------------- |
98
+ | Client | Root collection | Main user entity |
99
+ | Application | clients/{clientId}/applications/{applicationId} | References `clientId`, `vacancyId` |
100
+ | ApplicationQuestion | .../applications/{applicationId}/questions/{qId} | Subcollection of Application |
101
+ | ClientQuestion | clients/{clientId}/questions/{questionId} | Subcollection of Client |
102
+ | Vacancy | Root collection | Referenced by Application, VacancySuggestion |
103
+ | VacancySuggestion | clients/{clientId}/vacancySuggestions/{suggestionId} | References `clientId`, `vacancyId` |
104
+ | TargetPreferences | clients/{clientId}/preferences/targetPreferences | References `clientId`, contains `TargetJob[]` and `TargetLocation[]` |
105
+ | TargetJob | Embedded in TargetPreferences | Contains `category` (VacancyCategory) |
106
+ | TargetLocation | Embedded in TargetPreferences | List of preferred locations |
107
+ | Agent | Root collection | Standalone entity |
108
+ | AuthUser | Root collection | Standalone entity |
109
+ | ClientData | Root collection | Standalone entity |
110
+ | ClientLogin | clientLogins/{userId}/logins/{domain} | References `userId` |
111
+ | GmailMessage | clientEmails/{clientId}/messages/{messageId} | References `clientId` |
112
+ | ResumeLink | clients/{clientId}/resumeLinks/{linkId} | References `clientId`, stores PDF resume URLs |
113
+
114
+ **Notes:**
115
+
116
+ - Most subcollections are nested under `Client` (e.g., applications, questions, vacancySuggestions).
117
+ - `Application` and `VacancySuggestion` reference both `clientId` (parent) and `vacancyId` (target job).
118
+ - `TargetPreferences` embeds arrays of `TargetJob` and `TargetLocation`.
119
+ - All relationships are enforced by Firestore path structure and cross-referenced IDs.
120
+
121
+ ---
122
+
53
123
  ## ✅ Usage
54
124
 
125
+ This library is intentionally SDK-free. All Firebase logic — including `Timestamp`, `doc()`, and `onSnapshot()` — is handled in your app’s service layer. This ensures portability across React apps, Firebase functions, and testing environments.
126
+
55
127
  ### Importing Models and Paths
56
128
 
57
129
  ```ts
58
130
  import { Client } from "@jobsearch-works/firestore-models/types/Client";
59
- import { pathStrings } from "@jobsearch-works/firestore-models/paths/pathStrings";
131
+ import { firestorePaths } from "@jobsearch-works/firestore-models/paths/firestorePaths";
60
132
 
61
- const clientPath = pathStrings.client("abc123"); // → "clients/abc123"
133
+ const clientDocPath = firestorePaths.clients.doc("abc123"); // → "clients/abc123"
62
134
  ```
63
135
 
64
136
  ---
65
137
 
66
- ## 🔒 Type Definition Example
138
+ ## 📄 Firestore Models (Types)
139
+
140
+ All Firestore document schemas are defined as TypeScript interfaces in `src/types`. These are pure data types (SDK-free) and can be reused across apps, functions, and tests.
141
+
142
+ > **Why does every model include `id?: string`?**
143
+ > Firestore's `.data()` does **not** include the document ID. This library's types include `id` as an optional property, which is added manually when fetching data. This makes it easier to use models in UI, caching, and linking between entities.
144
+
145
+ ### Main Types (alphabetical)
146
+
147
+ - **Agent**
148
+
149
+ ```ts
150
+ export interface Agent {
151
+ id?: string;
152
+ name: string;
153
+ email: string;
154
+ status: "active" | "inactive";
155
+ profilePicture?: string;
156
+ createdAt?: Date | string;
157
+ updatedAt?: Date | string;
158
+ }
159
+ ```
160
+
161
+ - **Application**
162
+
163
+ ```ts
164
+ export interface Application {
165
+ id?: string;
166
+ vacancyId: string;
167
+ clientId: string;
168
+ status: ApplicationStatus;
169
+ assignedTo?: string;
170
+ coverLetter?: string;
171
+ resume?: string;
172
+ // Status timestamps
173
+ submittedAt?: Date | string;
174
+ interviewingAt?: Date | string;
175
+ acceptedAt?: Date | string;
176
+ rejectedAt?: Date | string;
177
+ withdrawnAt?: Date | string;
178
+ applyingAt?: Date | string;
179
+ suggestedAt?: Date | string;
180
+ approvedAt?: Date | string;
181
+ // Denormalized/snapshot fields from Vacancy
182
+ company?: string;
183
+ position?: string;
184
+ location?: string;
185
+ jobId?: string;
186
+ advertisingUrl?: string;
187
+ applicationUrl?: string;
188
+ applicationDomain?: string;
189
+ advertisingDomain?: string;
190
+ description?: string;
191
+ fullPageText?: string;
192
+ createdAt?: Date | string;
193
+ updatedAt?: Date | string;
194
+ }
195
+ ```
196
+
197
+ - `ApplicationStatus` values: new, submitted, interviewing, accepted, rejected, withdrawn, applying, suggested, approved
198
+
199
+ - **ApplicationQuestion**
200
+
201
+ ```ts
202
+ export interface ApplicationQuestion {
203
+ id?: string;
204
+ questionText: string;
205
+ answerText?: string;
206
+ type: "text" | "select";
207
+ createdAt?: Date | string;
208
+ updatedAt?: Date | string;
209
+ }
210
+ ```
211
+
212
+ - **AuthUser**
213
+
214
+ ```ts
215
+ export interface AuthUser {
216
+ id?: string;
217
+ email: string;
218
+ displayName?: string;
219
+ photoURL?: string;
220
+ lastSignIn?: string; // ISO string
221
+ emailVerified?: boolean;
222
+ createdAt?: Date | string;
223
+ updatedAt?: Date | string;
224
+ }
225
+ ```
226
+
227
+ - **Client**
228
+
229
+ ```ts
230
+ export interface Client {
231
+ id?: string;
232
+ name: string;
233
+ email: string;
234
+ status: "active" | "inactive";
235
+ resume?: string;
236
+ createdAt?: Date | string;
237
+ }
238
+ ```
239
+
240
+ - **ClientData**
241
+
242
+ ```ts
243
+ export interface ClientData {
244
+ id?: string;
245
+ firstName: string;
246
+ lastName: string;
247
+ middleName?: string;
248
+ preferredName?: string;
249
+ email: string;
250
+ phone: string;
251
+ address: string;
252
+ city: string;
253
+ suburb: string;
254
+ state: string;
255
+ zip: string;
256
+ country: string;
257
+ linkedIn?: string;
258
+ countryPhoneCode: string;
259
+ nationality: string;
260
+ dateOfBirth?: Date | string;
261
+ createdAt?: Date | string;
262
+ updatedAt?: Date | string;
263
+ }
264
+ ```
265
+
266
+ - **ClientLogin**
267
+
268
+ ```ts
269
+ export interface ClientLogin {
270
+ id?: string;
271
+ userId: string;
272
+ url: string;
273
+ domain: string;
274
+ username?: string;
275
+ password: string;
276
+ email?: string;
277
+ createdAt?: Date | string;
278
+ updatedAt?: Date | string;
279
+ }
280
+ ```
281
+
282
+ - **ClientQuestion**
283
+
284
+ ```ts
285
+ export interface ClientQuestion {
286
+ id?: string;
287
+ questionText: string;
288
+ answerText?: string;
289
+ type: "text" | "select";
290
+ options?: string[];
291
+ createdAt?: Date | string;
292
+ updatedAt?: Date | string;
293
+ }
294
+ ```
295
+
296
+ - **GmailMessage**
297
+
298
+ ```ts
299
+ export interface GmailMessage {
300
+ id?: string;
301
+ ```
302
+
303
+ - **ResumeLink**
304
+
305
+ ```ts
306
+ export interface ResumeLink {
307
+ id: string;
308
+ title: string;
309
+ url: string;
310
+ description: string;
311
+ createdAt: any; // Timestamp from firebase/firestore
312
+ createdBy: string;
313
+ clientId: string;
314
+ }
315
+ ```
316
+
317
+ - **GmailMessage**
318
+
319
+ ```ts
320
+ export interface GmailMessage {
321
+ id?: string;
322
+ messageId: string;
323
+ threadId?: string;
324
+ labelIds?: string[];
325
+ snippet?: string;
326
+ internalDate?: string;
327
+ payload?: object;
328
+ createdAt?: Date | string;
329
+ updatedAt?: Date | string;
330
+ }
331
+ ```
332
+
333
+ - **TargetJob**
334
+
335
+ ```ts
336
+ export interface TargetJob {
337
+ id?: string;
338
+ category: VacancyCategory;
339
+ position: string;
340
+ notes?: string;
341
+ }
342
+ ```
343
+
344
+ - **TargetLocation**
345
+
346
+ ```ts
347
+ export interface TargetLocation {
348
+ id?: string;
349
+ country: string;
350
+ cities: {
351
+ name: string;
352
+ areas: string[];
353
+ }[];
354
+ }
355
+ ```
356
+
357
+ - **TargetPreferences**
358
+
359
+ ```ts
360
+ export interface TargetPreferences {
361
+ id?: string;
362
+ clientId: string;
363
+ locations: TargetLocation[];
364
+ jobs: TargetJob[];
365
+ createdAt?: Date | string;
366
+ updatedAt?: Date | string;
367
+ }
368
+ ```
369
+
370
+ - **Vacancy**
371
+
372
+ ```ts
373
+ export interface Vacancy {
374
+ id?: string;
375
+ company: string;
376
+ position: string;
377
+ location: string;
378
+ description: string;
379
+ advertisingUrl: string;
380
+ applicationUrl: string;
381
+ applicationDomain: string;
382
+ advertisingDomain: string;
383
+ fullPageText: string;
384
+ jobId: string;
385
+ category: VacancyCategory;
386
+ suggestedTo?: string[];
387
+ createdAt?: Date | string;
388
+ updatedAt?: Date | string;
389
+ }
390
+ ```
391
+
392
+ - `VacancyCategory` includes: Accounting, IT, Healthcare, Sales, etc.
393
+
394
+ - **VacancySuggestion**
395
+ ```ts
396
+ export interface VacancySuggestion {
397
+ id?: string;
398
+ clientId: string;
399
+ vacancyId: string;
400
+ status: string;
401
+ createdAt?: Date | string;
402
+ }
403
+ ```
404
+
405
+ ---
406
+
407
+ ## 🗂️ Firestore Path Utilities
408
+
409
+ All Firestore collection/document path builders are centralized in `src/paths/firestorePaths.ts` as pure string helpers. **Every helper returns a Firestore path string, not a Firestore SDK reference.** This keeps the library SDK-free and fully portable for use in any environment (Node.js, browser, SSR, CLI, etc). No Firestore SDK is required or included.
410
+
411
+ ### Example Usage
67
412
 
68
413
  ```ts
69
- // types/Client.ts
70
- export interface Client {
71
- id?: string;
72
- name: string;
73
- email: string;
74
- status: "active" | "inactive";
75
- createdAt?: Date | string;
414
+ import { firestorePaths } from "@jobsearch-works/firestore-models/paths/firestorePaths";
415
+
416
+ const clientDoc = firestorePaths.clients.doc("clientId"); // "clients/clientId"
417
+ const appDoc = firestorePaths.clients.applications.doc(
418
+ "clientId",
419
+ "applicationId"
420
+ ); // "clients/clientId/applications/applicationId"
421
+ const vacancyDoc = firestorePaths.vacancies.doc("vacancyId"); // "vacancies/vacancyId"
422
+ ```
423
+
424
+ #### Fetching a Firestore Document and Including Its ID
425
+
426
+ ```ts
427
+ import { doc, getDoc } from "firebase/firestore";
428
+ import { firestore } from "../firebaseConfig";
429
+ import { firestorePaths } from "@jobsearch-works/firestore-models";
430
+
431
+ const ref = doc(firestore, firestorePaths.vacancies.doc("vac123"));
432
+ const snap = await getDoc(ref);
433
+ const vacancy = { id: snap.id, ...snap.data() };
434
+ ```
435
+
436
+ **Reusable withId Utility:**
437
+
438
+ ```ts
439
+ export function withId<T>(snap: DocumentSnapshot): T & { id: string } {
440
+ return { id: snap.id, ...snap.data() } as T & { id: string };
76
441
  }
77
442
  ```
78
443
 
444
+ #### Main Path Helpers
445
+
446
+ - `firestorePaths.clients.collection()` → "clients"
447
+ - `firestorePaths.clients.doc(clientId)` → "clients/{clientId}"
448
+ - `firestorePaths.clients.applications.collection(clientId)` → "clients/{clientId}/applications"
449
+ - `firestorePaths.clients.applications.doc(clientId, applicationId)` → "clients/{clientId}/applications/{applicationId}"
450
+ - `firestorePaths.clients.questions.collection(clientId)` → "clients/{clientId}/questions"
451
+ - `firestorePaths.clients.questions.doc(clientId, questionId)` → "clients/{clientId}/questions/{questionId}"
452
+ - `firestorePaths.clients.preferences.target(clientId)` → "clients/{clientId}/preferences/targetPreferences"
453
+ - `firestorePaths.clients.vacancySuggestions.collection(clientId)` → "clients/{clientId}/vacancySuggestions"
454
+ - `firestorePaths.clients.vacancySuggestions.doc(clientId, suggestionId)` → "clients/{clientId}/vacancySuggestions/{suggestionId}"
455
+ - `firestorePaths.users.collection()` → "users"
456
+ - `firestorePaths.users.doc(userId)` → "users/{userId}"
457
+ - `firestorePaths.vacancies.collection()` → "vacancies"
458
+ - `firestorePaths.vacancies.doc(vacancyId)` → "vacancies/{vacancyId}"
459
+ - `firestorePaths.agents.collection()` → "agents"
460
+ - `firestorePaths.agents.doc(agentId)` → "agents/{agentId}"
461
+ - `firestorePaths.clientData.collection()` → "clientData"
462
+ - `firestorePaths.clientData.doc(clientDataId)` → "clientData/{clientDataId}"
463
+ - `firestorePaths.clientLogins.collection(userId)` → "clientLogins/{userId}"
464
+ - `firestorePaths.clientLogins.doc(userId, domain)` → "clientLogins/{userId}/logins/{domain}"
465
+ - `firestorePaths.gmailMessages.collection(clientId)` → "clientEmails/{clientId}/messages"
466
+ - `firestorePaths.gmailMessages.doc(clientId, messageId)` → "clientEmails/{clientId}/messages/{messageId}"
467
+
468
+ ---
469
+
470
+ ## 🛡️ Notes
471
+
472
+ - All types and paths are SDK-independent and safe to use in any TypeScript/Node/React project.
473
+ - This package does not include any Firestore SDK or database logic—just models and helpers.
474
+ - For Firestore access, use your own service layer or SDK wrapper.
475
+ - This library follows semantic versioning and is safe for production use.
476
+
79
477
  ---
80
478
 
81
479
  ## 🔗 Path Builder Example
@@ -98,9 +496,3 @@ When adding a new model:
98
496
  2. Add its path builder in `src/paths/pathStrings.ts`
99
497
  3. Update the documentation if needed
100
498
  4. Maintain backward compatibility
101
-
102
- ---
103
-
104
- ## 📄 License
105
-
106
- MIT
package/dist/index.d.mts CHANGED
@@ -1,10 +1,11 @@
1
+ type ClientStatus = "active" | "inactive";
1
2
  interface Client {
2
- id?: string;
3
- name: string;
4
- email: string;
5
- status: "active" | "inactive";
6
- resume?: string;
7
- createdAt?: Date | string;
3
+ readonly id?: string;
4
+ readonly name: string;
5
+ readonly email: string;
6
+ readonly status: ClientStatus;
7
+ readonly resume?: string;
8
+ readonly createdAt?: Date | string;
8
9
  }
9
10
 
10
11
  declare const ApplicationStatus: {
@@ -111,14 +112,15 @@ interface Vacancy {
111
112
  updatedAt?: Date | string;
112
113
  }
113
114
 
115
+ type AgentStatus = "active" | "inactive";
114
116
  interface Agent {
115
- id?: string;
116
- name: string;
117
- email: string;
118
- status: "active" | "inactive";
119
- profilePicture?: string;
120
- createdAt?: Date | string;
121
- updatedAt?: Date | string;
117
+ readonly id?: string;
118
+ readonly name: string;
119
+ readonly email: string;
120
+ readonly status: AgentStatus;
121
+ readonly profilePicture?: string;
122
+ readonly createdAt?: Date | string;
123
+ readonly updatedAt?: Date | string;
122
124
  }
123
125
 
124
126
  type ClientQuestionType = "text" | "select";
@@ -179,6 +181,7 @@ interface ApplicationQuestion {
179
181
  }
180
182
 
181
183
  interface VacancySuggestion {
184
+ id?: string;
182
185
  clientId: string;
183
186
  vacancyId: string;
184
187
  status: string;
@@ -212,6 +215,7 @@ interface GmailMessage {
212
215
  }
213
216
 
214
217
  interface TargetLocation {
218
+ id?: string;
215
219
  country: string;
216
220
  cities: {
217
221
  name: string;
@@ -220,13 +224,14 @@ interface TargetLocation {
220
224
  }
221
225
 
222
226
  interface TargetJob {
227
+ id?: string;
223
228
  category: VacancyCategory;
224
229
  position: string;
225
230
  notes?: string;
226
231
  }
227
232
 
228
233
  interface TargetPreferences {
229
- id: string;
234
+ id?: string;
230
235
  clientId: string;
231
236
  locations: TargetLocation[];
232
237
  jobs: TargetJob[];
@@ -234,30 +239,68 @@ interface TargetPreferences {
234
239
  updatedAt: Date;
235
240
  }
236
241
 
237
- declare const pathStrings: {
238
- readonly clients: () => string;
239
- readonly client: (clientId: string) => string;
240
- readonly applications: (clientId: string) => string;
241
- readonly application: (clientId: string, applicationId: string) => string;
242
- readonly users: () => string;
243
- readonly user: (userId: string) => string;
244
- readonly vacancies: () => string;
245
- readonly vacancy: (vacancyId: string) => string;
246
- readonly agents: () => string;
247
- readonly agent: (agentId: string) => string;
248
- readonly clientQuestions: (clientId: string) => string;
249
- readonly clientQuestion: (clientId: string, questionId: string) => string;
250
- readonly clientData: () => string;
251
- readonly clientDataItem: (clientDataId: string) => string;
252
- readonly clientLogins: (userId: string) => string;
253
- readonly clientLogin: (userId: string, domain: string) => string;
254
- readonly applicationQuestions: (clientId: string, applicationId: string) => string;
255
- readonly applicationQuestion: (clientId: string, applicationId: string, questionId: string) => string;
256
- readonly vacancySuggestions: (clientId: string) => string;
257
- readonly vacancySuggestion: (clientId: string, suggestionId: string) => string;
258
- readonly gmailMessages: (clientId: string) => string;
259
- readonly gmailMessage: (clientId: string, messageId: string) => string;
260
- readonly targetPreferences: (clientId: string) => string;
242
+ interface ResumeLink {
243
+ id?: string;
244
+ title: string;
245
+ url: string;
246
+ description: string;
247
+ createdAt?: Date | string;
248
+ createdBy: string;
249
+ clientId: string;
250
+ }
251
+
252
+ declare const firestorePaths: {
253
+ readonly clients: {
254
+ readonly collection: () => string;
255
+ readonly doc: (clientId: string) => string;
256
+ readonly applications: {
257
+ readonly collection: (clientId: string) => string;
258
+ readonly doc: (clientId: string, applicationId: string) => string;
259
+ readonly questions: {
260
+ readonly collection: (clientId: string, applicationId: string) => string;
261
+ readonly doc: (clientId: string, applicationId: string, questionId: string) => string;
262
+ };
263
+ };
264
+ readonly questions: {
265
+ readonly collection: (clientId: string) => string;
266
+ readonly doc: (clientId: string, questionId: string) => string;
267
+ };
268
+ readonly preferences: {
269
+ readonly target: (clientId: string) => string;
270
+ };
271
+ readonly vacancySuggestions: {
272
+ readonly collection: (clientId: string) => string;
273
+ readonly doc: (clientId: string, suggestionId: string) => string;
274
+ };
275
+ };
276
+ readonly users: {
277
+ readonly collection: () => string;
278
+ readonly doc: (userId: string) => string;
279
+ };
280
+ readonly vacancies: {
281
+ readonly collection: () => string;
282
+ readonly doc: (vacancyId: string) => string;
283
+ };
284
+ readonly agents: {
285
+ readonly collection: () => string;
286
+ readonly doc: (agentId: string) => string;
287
+ };
288
+ readonly clientData: {
289
+ readonly collection: () => string;
290
+ readonly doc: (clientDataId: string) => string;
291
+ };
292
+ readonly clientLogins: {
293
+ readonly collection: (userId: string) => string;
294
+ readonly doc: (userId: string, domain: string) => string;
295
+ };
296
+ readonly gmailMessages: {
297
+ readonly collection: (clientId: string) => string;
298
+ readonly doc: (clientId: string, messageId: string) => string;
299
+ };
300
+ readonly resumeLinks: {
301
+ readonly collection: (clientId: string) => string;
302
+ readonly doc: (clientId: string, resumeLinkId: string) => string;
303
+ };
261
304
  };
262
305
 
263
- export { Agent, Application, ApplicationQuestion, ApplicationQuestionType, ApplicationQuestionTypeOptions, ApplicationStatus, AuthUser, Client, ClientData, ClientLogin, ClientQuestion, ClientQuestionType, ClientQuestionTypeOptions, GmailMessage, TargetJob, TargetLocation, TargetPreferences, Vacancy, VacancyCategory, VacancySuggestion, pathStrings };
306
+ export { Agent, AgentStatus, Application, ApplicationQuestion, ApplicationQuestionType, ApplicationQuestionTypeOptions, ApplicationStatus, AuthUser, Client, ClientData, ClientLogin, ClientQuestion, ClientQuestionType, ClientQuestionTypeOptions, ClientStatus, GmailMessage, ResumeLink, TargetJob, TargetLocation, TargetPreferences, Vacancy, VacancyCategory, VacancySuggestion, firestorePaths };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,11 @@
1
+ type ClientStatus = "active" | "inactive";
1
2
  interface Client {
2
- id?: string;
3
- name: string;
4
- email: string;
5
- status: "active" | "inactive";
6
- resume?: string;
7
- createdAt?: Date | string;
3
+ readonly id?: string;
4
+ readonly name: string;
5
+ readonly email: string;
6
+ readonly status: ClientStatus;
7
+ readonly resume?: string;
8
+ readonly createdAt?: Date | string;
8
9
  }
9
10
 
10
11
  declare const ApplicationStatus: {
@@ -111,14 +112,15 @@ interface Vacancy {
111
112
  updatedAt?: Date | string;
112
113
  }
113
114
 
115
+ type AgentStatus = "active" | "inactive";
114
116
  interface Agent {
115
- id?: string;
116
- name: string;
117
- email: string;
118
- status: "active" | "inactive";
119
- profilePicture?: string;
120
- createdAt?: Date | string;
121
- updatedAt?: Date | string;
117
+ readonly id?: string;
118
+ readonly name: string;
119
+ readonly email: string;
120
+ readonly status: AgentStatus;
121
+ readonly profilePicture?: string;
122
+ readonly createdAt?: Date | string;
123
+ readonly updatedAt?: Date | string;
122
124
  }
123
125
 
124
126
  type ClientQuestionType = "text" | "select";
@@ -179,6 +181,7 @@ interface ApplicationQuestion {
179
181
  }
180
182
 
181
183
  interface VacancySuggestion {
184
+ id?: string;
182
185
  clientId: string;
183
186
  vacancyId: string;
184
187
  status: string;
@@ -212,6 +215,7 @@ interface GmailMessage {
212
215
  }
213
216
 
214
217
  interface TargetLocation {
218
+ id?: string;
215
219
  country: string;
216
220
  cities: {
217
221
  name: string;
@@ -220,13 +224,14 @@ interface TargetLocation {
220
224
  }
221
225
 
222
226
  interface TargetJob {
227
+ id?: string;
223
228
  category: VacancyCategory;
224
229
  position: string;
225
230
  notes?: string;
226
231
  }
227
232
 
228
233
  interface TargetPreferences {
229
- id: string;
234
+ id?: string;
230
235
  clientId: string;
231
236
  locations: TargetLocation[];
232
237
  jobs: TargetJob[];
@@ -234,30 +239,68 @@ interface TargetPreferences {
234
239
  updatedAt: Date;
235
240
  }
236
241
 
237
- declare const pathStrings: {
238
- readonly clients: () => string;
239
- readonly client: (clientId: string) => string;
240
- readonly applications: (clientId: string) => string;
241
- readonly application: (clientId: string, applicationId: string) => string;
242
- readonly users: () => string;
243
- readonly user: (userId: string) => string;
244
- readonly vacancies: () => string;
245
- readonly vacancy: (vacancyId: string) => string;
246
- readonly agents: () => string;
247
- readonly agent: (agentId: string) => string;
248
- readonly clientQuestions: (clientId: string) => string;
249
- readonly clientQuestion: (clientId: string, questionId: string) => string;
250
- readonly clientData: () => string;
251
- readonly clientDataItem: (clientDataId: string) => string;
252
- readonly clientLogins: (userId: string) => string;
253
- readonly clientLogin: (userId: string, domain: string) => string;
254
- readonly applicationQuestions: (clientId: string, applicationId: string) => string;
255
- readonly applicationQuestion: (clientId: string, applicationId: string, questionId: string) => string;
256
- readonly vacancySuggestions: (clientId: string) => string;
257
- readonly vacancySuggestion: (clientId: string, suggestionId: string) => string;
258
- readonly gmailMessages: (clientId: string) => string;
259
- readonly gmailMessage: (clientId: string, messageId: string) => string;
260
- readonly targetPreferences: (clientId: string) => string;
242
+ interface ResumeLink {
243
+ id?: string;
244
+ title: string;
245
+ url: string;
246
+ description: string;
247
+ createdAt?: Date | string;
248
+ createdBy: string;
249
+ clientId: string;
250
+ }
251
+
252
+ declare const firestorePaths: {
253
+ readonly clients: {
254
+ readonly collection: () => string;
255
+ readonly doc: (clientId: string) => string;
256
+ readonly applications: {
257
+ readonly collection: (clientId: string) => string;
258
+ readonly doc: (clientId: string, applicationId: string) => string;
259
+ readonly questions: {
260
+ readonly collection: (clientId: string, applicationId: string) => string;
261
+ readonly doc: (clientId: string, applicationId: string, questionId: string) => string;
262
+ };
263
+ };
264
+ readonly questions: {
265
+ readonly collection: (clientId: string) => string;
266
+ readonly doc: (clientId: string, questionId: string) => string;
267
+ };
268
+ readonly preferences: {
269
+ readonly target: (clientId: string) => string;
270
+ };
271
+ readonly vacancySuggestions: {
272
+ readonly collection: (clientId: string) => string;
273
+ readonly doc: (clientId: string, suggestionId: string) => string;
274
+ };
275
+ };
276
+ readonly users: {
277
+ readonly collection: () => string;
278
+ readonly doc: (userId: string) => string;
279
+ };
280
+ readonly vacancies: {
281
+ readonly collection: () => string;
282
+ readonly doc: (vacancyId: string) => string;
283
+ };
284
+ readonly agents: {
285
+ readonly collection: () => string;
286
+ readonly doc: (agentId: string) => string;
287
+ };
288
+ readonly clientData: {
289
+ readonly collection: () => string;
290
+ readonly doc: (clientDataId: string) => string;
291
+ };
292
+ readonly clientLogins: {
293
+ readonly collection: (userId: string) => string;
294
+ readonly doc: (userId: string, domain: string) => string;
295
+ };
296
+ readonly gmailMessages: {
297
+ readonly collection: (clientId: string) => string;
298
+ readonly doc: (clientId: string, messageId: string) => string;
299
+ };
300
+ readonly resumeLinks: {
301
+ readonly collection: (clientId: string) => string;
302
+ readonly doc: (clientId: string, resumeLinkId: string) => string;
303
+ };
261
304
  };
262
305
 
263
- export { Agent, Application, ApplicationQuestion, ApplicationQuestionType, ApplicationQuestionTypeOptions, ApplicationStatus, AuthUser, Client, ClientData, ClientLogin, ClientQuestion, ClientQuestionType, ClientQuestionTypeOptions, GmailMessage, TargetJob, TargetLocation, TargetPreferences, Vacancy, VacancyCategory, VacancySuggestion, pathStrings };
306
+ export { Agent, AgentStatus, Application, ApplicationQuestion, ApplicationQuestionType, ApplicationQuestionTypeOptions, ApplicationStatus, AuthUser, Client, ClientData, ClientLogin, ClientQuestion, ClientQuestionType, ClientQuestionTypeOptions, ClientStatus, GmailMessage, ResumeLink, TargetJob, TargetLocation, TargetPreferences, Vacancy, VacancyCategory, VacancySuggestion, firestorePaths };
package/dist/index.js CHANGED
@@ -24,7 +24,7 @@ __export(src_exports, {
24
24
  ApplicationStatus: () => ApplicationStatus,
25
25
  ClientQuestionTypeOptions: () => ClientQuestionTypeOptions,
26
26
  VacancyCategory: () => VacancyCategory,
27
- pathStrings: () => pathStrings
27
+ firestorePaths: () => firestorePaths
28
28
  });
29
29
  module.exports = __toCommonJS(src_exports);
30
30
 
@@ -84,42 +84,59 @@ var ClientQuestionTypeOptions = [
84
84
  // src/types/ApplicationQuestion.ts
85
85
  var ApplicationQuestionTypeOptions = ["text", "select"];
86
86
 
87
- // src/paths/pathStrings.ts
88
- var pathStrings = {
89
- clients: () => "clients",
90
- client: (clientId) => `clients/${clientId}`,
91
- // Application paths
92
- applications: (clientId) => `clients/${clientId}/applications`,
93
- application: (clientId, applicationId) => `clients/${clientId}/applications/${applicationId}`,
94
- // AuthUser paths
95
- users: () => "users",
96
- user: (userId) => `users/${userId}`,
97
- // Vacancy paths
98
- vacancies: () => "vacancies",
99
- vacancy: (vacancyId) => `vacancies/${vacancyId}`,
100
- // Agent paths
101
- agents: () => "agents",
102
- agent: (agentId) => `agents/${agentId}`,
103
- // ClientQuestion paths
104
- clientQuestions: (clientId) => `clients/${clientId}/questions`,
105
- clientQuestion: (clientId, questionId) => `clients/${clientId}/questions/${questionId}`,
106
- // ClientData paths
107
- clientData: () => "clientData",
108
- clientDataItem: (clientDataId) => `clientData/${clientDataId}`,
109
- // ClientLogin paths
110
- clientLogins: (userId) => `clientLogins/${userId}`,
111
- clientLogin: (userId, domain) => `clientLogins/${userId}/logins/${domain}`,
112
- // ApplicationQuestion paths
113
- applicationQuestions: (clientId, applicationId) => `clients/${clientId}/applications/${applicationId}/questions`,
114
- applicationQuestion: (clientId, applicationId, questionId) => `clients/${clientId}/applications/${applicationId}/questions/${questionId}`,
115
- // VacancySuggestion paths
116
- vacancySuggestions: (clientId) => `clients/${clientId}/vacancySuggestions`,
117
- vacancySuggestion: (clientId, suggestionId) => `clients/${clientId}/vacancySuggestions/${suggestionId}`,
118
- // GmailMessage paths
119
- gmailMessages: (clientId) => `clientEmails/${clientId}/messages`,
120
- gmailMessage: (clientId, messageId) => `clientEmails/${clientId}/messages/${messageId}`,
121
- // TargetPreferences paths
122
- targetPreferences: (clientId) => `clients/${clientId}/preferences/targetPreferences`
87
+ // src/paths/firestorePaths.ts
88
+ var firestorePaths = {
89
+ clients: {
90
+ collection: () => "clients",
91
+ doc: (clientId) => `clients/${clientId}`,
92
+ applications: {
93
+ collection: (clientId) => `clients/${clientId}/applications`,
94
+ doc: (clientId, applicationId) => `clients/${clientId}/applications/${applicationId}`,
95
+ questions: {
96
+ collection: (clientId, applicationId) => `clients/${clientId}/applications/${applicationId}/questions`,
97
+ doc: (clientId, applicationId, questionId) => `clients/${clientId}/applications/${applicationId}/questions/${questionId}`
98
+ }
99
+ },
100
+ questions: {
101
+ collection: (clientId) => `clients/${clientId}/questions`,
102
+ doc: (clientId, questionId) => `clients/${clientId}/questions/${questionId}`
103
+ },
104
+ preferences: {
105
+ target: (clientId) => `clients/${clientId}/preferences/targetPreferences`
106
+ },
107
+ vacancySuggestions: {
108
+ collection: (clientId) => `clients/${clientId}/vacancySuggestions`,
109
+ doc: (clientId, suggestionId) => `clients/${clientId}/vacancySuggestions/${suggestionId}`
110
+ }
111
+ },
112
+ users: {
113
+ collection: () => "users",
114
+ doc: (userId) => `users/${userId}`
115
+ },
116
+ vacancies: {
117
+ collection: () => "vacancies",
118
+ doc: (vacancyId) => `vacancies/${vacancyId}`
119
+ },
120
+ agents: {
121
+ collection: () => "agents",
122
+ doc: (agentId) => `agents/${agentId}`
123
+ },
124
+ clientData: {
125
+ collection: () => "clientData",
126
+ doc: (clientDataId) => `clientData/${clientDataId}`
127
+ },
128
+ clientLogins: {
129
+ collection: (userId) => `clientLogins/${userId}/logins`,
130
+ doc: (userId, domain) => `clientLogins/${userId}/logins/${domain}`
131
+ },
132
+ gmailMessages: {
133
+ collection: (clientId) => `clientEmails/${clientId}/messages`,
134
+ doc: (clientId, messageId) => `clientEmails/${clientId}/messages/${messageId}`
135
+ },
136
+ resumeLinks: {
137
+ collection: (clientId) => `clients/${clientId}/resumeLinks`,
138
+ doc: (clientId, resumeLinkId) => `clients/${clientId}/resumeLinks/${resumeLinkId}`
139
+ }
123
140
  };
124
141
  // Annotate the CommonJS export names for ESM import in node:
125
142
  0 && (module.exports = {
@@ -127,5 +144,5 @@ var pathStrings = {
127
144
  ApplicationStatus,
128
145
  ClientQuestionTypeOptions,
129
146
  VacancyCategory,
130
- pathStrings
147
+ firestorePaths
131
148
  });
package/dist/index.mjs CHANGED
@@ -54,47 +54,64 @@ var ClientQuestionTypeOptions = [
54
54
  // src/types/ApplicationQuestion.ts
55
55
  var ApplicationQuestionTypeOptions = ["text", "select"];
56
56
 
57
- // src/paths/pathStrings.ts
58
- var pathStrings = {
59
- clients: () => "clients",
60
- client: (clientId) => `clients/${clientId}`,
61
- // Application paths
62
- applications: (clientId) => `clients/${clientId}/applications`,
63
- application: (clientId, applicationId) => `clients/${clientId}/applications/${applicationId}`,
64
- // AuthUser paths
65
- users: () => "users",
66
- user: (userId) => `users/${userId}`,
67
- // Vacancy paths
68
- vacancies: () => "vacancies",
69
- vacancy: (vacancyId) => `vacancies/${vacancyId}`,
70
- // Agent paths
71
- agents: () => "agents",
72
- agent: (agentId) => `agents/${agentId}`,
73
- // ClientQuestion paths
74
- clientQuestions: (clientId) => `clients/${clientId}/questions`,
75
- clientQuestion: (clientId, questionId) => `clients/${clientId}/questions/${questionId}`,
76
- // ClientData paths
77
- clientData: () => "clientData",
78
- clientDataItem: (clientDataId) => `clientData/${clientDataId}`,
79
- // ClientLogin paths
80
- clientLogins: (userId) => `clientLogins/${userId}`,
81
- clientLogin: (userId, domain) => `clientLogins/${userId}/logins/${domain}`,
82
- // ApplicationQuestion paths
83
- applicationQuestions: (clientId, applicationId) => `clients/${clientId}/applications/${applicationId}/questions`,
84
- applicationQuestion: (clientId, applicationId, questionId) => `clients/${clientId}/applications/${applicationId}/questions/${questionId}`,
85
- // VacancySuggestion paths
86
- vacancySuggestions: (clientId) => `clients/${clientId}/vacancySuggestions`,
87
- vacancySuggestion: (clientId, suggestionId) => `clients/${clientId}/vacancySuggestions/${suggestionId}`,
88
- // GmailMessage paths
89
- gmailMessages: (clientId) => `clientEmails/${clientId}/messages`,
90
- gmailMessage: (clientId, messageId) => `clientEmails/${clientId}/messages/${messageId}`,
91
- // TargetPreferences paths
92
- targetPreferences: (clientId) => `clients/${clientId}/preferences/targetPreferences`
57
+ // src/paths/firestorePaths.ts
58
+ var firestorePaths = {
59
+ clients: {
60
+ collection: () => "clients",
61
+ doc: (clientId) => `clients/${clientId}`,
62
+ applications: {
63
+ collection: (clientId) => `clients/${clientId}/applications`,
64
+ doc: (clientId, applicationId) => `clients/${clientId}/applications/${applicationId}`,
65
+ questions: {
66
+ collection: (clientId, applicationId) => `clients/${clientId}/applications/${applicationId}/questions`,
67
+ doc: (clientId, applicationId, questionId) => `clients/${clientId}/applications/${applicationId}/questions/${questionId}`
68
+ }
69
+ },
70
+ questions: {
71
+ collection: (clientId) => `clients/${clientId}/questions`,
72
+ doc: (clientId, questionId) => `clients/${clientId}/questions/${questionId}`
73
+ },
74
+ preferences: {
75
+ target: (clientId) => `clients/${clientId}/preferences/targetPreferences`
76
+ },
77
+ vacancySuggestions: {
78
+ collection: (clientId) => `clients/${clientId}/vacancySuggestions`,
79
+ doc: (clientId, suggestionId) => `clients/${clientId}/vacancySuggestions/${suggestionId}`
80
+ }
81
+ },
82
+ users: {
83
+ collection: () => "users",
84
+ doc: (userId) => `users/${userId}`
85
+ },
86
+ vacancies: {
87
+ collection: () => "vacancies",
88
+ doc: (vacancyId) => `vacancies/${vacancyId}`
89
+ },
90
+ agents: {
91
+ collection: () => "agents",
92
+ doc: (agentId) => `agents/${agentId}`
93
+ },
94
+ clientData: {
95
+ collection: () => "clientData",
96
+ doc: (clientDataId) => `clientData/${clientDataId}`
97
+ },
98
+ clientLogins: {
99
+ collection: (userId) => `clientLogins/${userId}/logins`,
100
+ doc: (userId, domain) => `clientLogins/${userId}/logins/${domain}`
101
+ },
102
+ gmailMessages: {
103
+ collection: (clientId) => `clientEmails/${clientId}/messages`,
104
+ doc: (clientId, messageId) => `clientEmails/${clientId}/messages/${messageId}`
105
+ },
106
+ resumeLinks: {
107
+ collection: (clientId) => `clients/${clientId}/resumeLinks`,
108
+ doc: (clientId, resumeLinkId) => `clients/${clientId}/resumeLinks/${resumeLinkId}`
109
+ }
93
110
  };
94
111
  export {
95
112
  ApplicationQuestionTypeOptions,
96
113
  ApplicationStatus,
97
114
  ClientQuestionTypeOptions,
98
115
  VacancyCategory,
99
- pathStrings
116
+ firestorePaths
100
117
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobsearch-works/firestore-models",
3
- "version": "1.1.8",
3
+ "version": "1.1.10",
4
4
  "description": "A shared library for standardizing Firestore document schemas and paths across multiple projects",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",