@jobsearch-works/firestore-models 1.0.2 → 1.0.7

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
@@ -24,22 +24,270 @@ npm install @jsw/firestore-models
24
24
  yarn add @jsw/firestore-models
25
25
  ```
26
26
 
27
+ ## Project Structure
28
+
29
+ ```
30
+ firestore-models/
31
+ ├── src/
32
+ │ ├── models/ # All Firestore models
33
+ │ │ ├── Application.ts
34
+ │ │ ├── AuthUser.ts
35
+ │ │ ├── Client.ts
36
+ │ │ ├── ClientData.ts
37
+ │ │ ├── ClientLogin.ts
38
+ │ │ ├── Question.ts
39
+ │ │ ├── UserQuestion.ts
40
+ │ │ ├── Vacancy.ts
41
+ │ │ └── VacancySuggestion.ts
42
+ │ ├── BaseModel.ts # Base interface for all models
43
+ │ └── index.ts # Main entry point
44
+ ├── dist/ # Compiled output
45
+ └── package.json
46
+ ```
47
+
48
+ ## Base Model
49
+
50
+ All models extend from the BaseModel interface:
51
+
52
+ ```typescript
53
+ interface BaseModel {
54
+ id?: string; // Optional document ID
55
+ createdAt?: Date | string; // Optional creation timestamp
56
+ updatedAt?: Date | string; // Optional update timestamp
57
+ }
58
+ ```
59
+
60
+ ## Models and Namespaces
61
+
62
+ Each model is defined within its own namespace, which includes:
63
+
64
+ - The model interface
65
+ - Path builders for Firestore collections and documents
66
+ - Utility functions for working with the model
67
+
68
+ ### Client
69
+
70
+ ```typescript
71
+ namespace Client {
72
+ interface Model extends BaseModel {
73
+ name: string;
74
+ email: string;
75
+ status: "active" | "inactive";
76
+ resume?: string;
77
+ }
78
+
79
+ // Path builders
80
+ const collection = () => "clients";
81
+ const document = (clientId: string) => `clients/${clientId}`;
82
+
83
+ // Utility functions
84
+ const formatClient = (client: Client.Model): string;
85
+ const createNew = (name: string, email: string): Client.Model;
86
+ }
87
+ ```
88
+
89
+ ### Application
90
+
91
+ ```typescript
92
+ namespace Application {
93
+ interface Model extends BaseModel {
94
+ vacancyId: string;
95
+ clientId: string;
96
+ status:
97
+ | "new"
98
+ | "submitted"
99
+ | "interviewing"
100
+ | "accepted"
101
+ | "rejected"
102
+ | "withdrawn"
103
+ | "applying"
104
+ | "suggested"
105
+ | "approved";
106
+ coverLetter?: string;
107
+ resume?: string;
108
+ // Denormalized fields from Vacancy
109
+ company?: string;
110
+ position?: string;
111
+ location?: string;
112
+ jobId?: string;
113
+ advertisingUrl?: string;
114
+ applicationUrl?: string;
115
+ applicationDomain?: string;
116
+ advertisingDomain?: string;
117
+ description?: string;
118
+ fullPageText?: string;
119
+ }
120
+
121
+ // Path builders
122
+ const collection = (clientId: string) => `clients/${clientId}/applications`;
123
+ const document = (clientId: string, applicationId: string) =>
124
+ `clients/${clientId}/applications/${applicationId}`;
125
+
126
+ // Utility functions
127
+ const formatSummary = (application: Application.Model): string;
128
+ const formatDate = (date: Date | string): string;
129
+ const createNew = (
130
+ clientId: string,
131
+ vacancyId: string,
132
+ vacancyData: Partial<Vacancy.Model>
133
+ ): Application.Model;
134
+ const updateStatus = (
135
+ application: Application.Model,
136
+ newStatus: Application.Model["status"]
137
+ ): Application.Model;
138
+ }
139
+ ```
140
+
141
+ ### AuthUser
142
+
143
+ ```typescript
144
+ namespace AuthUser {
145
+ interface Model extends BaseModel {
146
+ email: string;
147
+ displayName?: string;
148
+ photoURL?: string;
149
+ lastSignIn?: Date | string;
150
+ emailVerified?: boolean;
151
+ }
152
+
153
+ // Path builders
154
+ const collection = () => "users";
155
+ const document = (userId: string) => `users/${userId}`;
156
+
157
+ // Utility functions
158
+ const fromFirebaseUser = (user: any): AuthUser.Model;
159
+ const formatDates = (user: AuthUser.Model): Record<string, string>;
160
+ const toFirestore = (user: AuthUser.Model): Record<string, any>;
161
+ const fromFirestore = (data: Record<string, any>): AuthUser.Model;
162
+ }
163
+ ```
164
+
165
+ ### Vacancy
166
+
167
+ ```typescript
168
+ namespace Vacancy {
169
+ interface Model extends BaseModel {
170
+ company: string;
171
+ position: string;
172
+ location: string;
173
+ jobId: string;
174
+ advertisingUrl: string;
175
+ applicationUrl: string;
176
+ applicationDomain: string;
177
+ advertisingDomain: string;
178
+ description: string;
179
+ fullPageText: string;
180
+ status: "active" | "inactive";
181
+ }
182
+
183
+ // Path builders
184
+ const collection = () => "vacancies";
185
+ const document = (vacancyId: string) => `vacancies/${vacancyId}`;
186
+ }
187
+ ```
188
+
189
+ ### Question
190
+
191
+ ```typescript
192
+ namespace Question {
193
+ interface Model extends BaseModel {
194
+ text: string;
195
+ type: "text" | "multiple_choice" | "single_choice";
196
+ options?: string[];
197
+ required: boolean;
198
+ order: number;
199
+ }
200
+
201
+ // Path builders
202
+ const collection = () => "questions";
203
+ const document = (questionId: string) => `questions/${questionId}`;
204
+ }
205
+ ```
206
+
207
+ ### UserQuestion
208
+
209
+ ```typescript
210
+ namespace UserQuestion {
211
+ interface Model extends BaseModel {
212
+ clientId: string;
213
+ questionId: string;
214
+ answer: string;
215
+ }
216
+
217
+ // Path builders
218
+ const collection = (clientId: string) => `clients/${clientId}/questions`;
219
+ const document = (clientId: string, questionId: string) =>
220
+ `clients/${clientId}/questions/${questionId}`;
221
+ }
222
+ ```
223
+
224
+ ### ClientData
225
+
226
+ ```typescript
227
+ namespace ClientData {
228
+ interface Model extends BaseModel {
229
+ clientId: string;
230
+ key: string;
231
+ value: any;
232
+ }
233
+
234
+ // Path builders
235
+ const collection = (clientId: string) => `clients/${clientId}/data`;
236
+ const document = (clientId: string, key: string) =>
237
+ `clients/${clientId}/data/${key}`;
238
+ }
239
+ ```
240
+
241
+ ### ClientLogin
242
+
243
+ ```typescript
244
+ namespace ClientLogin {
245
+ interface Model extends BaseModel {
246
+ clientId: string;
247
+ ipAddress: string;
248
+ userAgent: string;
249
+ }
250
+
251
+ // Path builders
252
+ const collection = (clientId: string) => `clients/${clientId}/logins`;
253
+ const document = (clientId: string, loginId: string) =>
254
+ `clients/${clientId}/logins/${loginId}`;
255
+ }
256
+ ```
257
+
258
+ ### VacancySuggestion
259
+
260
+ ```typescript
261
+ namespace VacancySuggestion {
262
+ interface Model extends BaseModel {
263
+ clientId: string;
264
+ vacancyId: string;
265
+ status: "pending" | "accepted" | "rejected";
266
+ }
267
+
268
+ // Path builders
269
+ const collection = (clientId: string) => `clients/${clientId}/suggestions`;
270
+ const document = (clientId: string, suggestionId: string) =>
271
+ `clients/${clientId}/suggestions/${suggestionId}`;
272
+ }
273
+ ```
274
+
27
275
  ## Usage
28
276
 
29
- Import the models and path builders in your application:
277
+ Import the models and their utilities in your application:
30
278
 
31
279
  ```typescript
32
- import { User, userPath } from "@jsw/firestore-models";
280
+ import { Client } from "@jsw/firestore-models";
281
+
282
+ // Create a new client
283
+ const newClient = Client.createNew("John Doe", "john@example.com");
33
284
 
34
- // Use the type-safe model
35
- const user: User = {
36
- id: "123",
37
- name: "John Doe",
38
- email: "john@example.com",
39
- };
285
+ // Use the path builders
286
+ const clientDocPath = Client.document("123"); // returns 'clients/123'
287
+ const clientCollectionPath = Client.collection(); // returns 'clients'
40
288
 
41
- // Use the path builder
42
- const userDocPath = userPath("123"); // returns 'users/123'
289
+ // Use the utility functions
290
+ const formattedClient = Client.formatClient(newClient);
43
291
  ```
44
292
 
45
293
  ## Contributing
package/dist/index.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  export * from "./BaseModel";
2
- export * from "./models/Application";
3
- export * from "./models/AuthUser";
4
- export * from "./models/Client";
5
- export * from "./models/ClientData";
6
- export * from "./models/ClientLogin";
7
- export * from "./models/Question";
8
- export * from "./models/UserQuestion";
9
- export * from "./models/Vacancy";
10
- export * from "./models/VacancySuggestion";
2
+ import * as Application from "./models/Application";
3
+ import * as AuthUser from "./models/AuthUser";
4
+ import * as Client from "./models/Client";
5
+ import * as ClientData from "./models/ClientData";
6
+ import * as ClientLogin from "./models/ClientLogin";
7
+ import * as Question from "./models/Question";
8
+ import * as UserQuestion from "./models/UserQuestion";
9
+ import * as Vacancy from "./models/Vacancy";
10
+ import * as VacancySuggestion from "./models/VacancySuggestion";
11
+ export { Application, AuthUser, Client, ClientData, ClientLogin, Question, UserQuestion, Vacancy, VacancySuggestion, };
package/dist/index.js CHANGED
@@ -1,12 +1,13 @@
1
1
  // Re-export base model
2
2
  export * from "./BaseModel";
3
3
  // Re-export all models
4
- export * from "./models/Application";
5
- export * from "./models/AuthUser";
6
- export * from "./models/Client";
7
- export * from "./models/ClientData";
8
- export * from "./models/ClientLogin";
9
- export * from "./models/Question";
10
- export * from "./models/UserQuestion";
11
- export * from "./models/Vacancy";
12
- export * from "./models/VacancySuggestion";
4
+ import * as Application from "./models/Application";
5
+ import * as AuthUser from "./models/AuthUser";
6
+ import * as Client from "./models/Client";
7
+ import * as ClientData from "./models/ClientData";
8
+ import * as ClientLogin from "./models/ClientLogin";
9
+ import * as Question from "./models/Question";
10
+ import * as UserQuestion from "./models/UserQuestion";
11
+ import * as Vacancy from "./models/Vacancy";
12
+ import * as VacancySuggestion from "./models/VacancySuggestion";
13
+ export { Application, AuthUser, Client, ClientData, ClientLogin, Question, UserQuestion, Vacancy, VacancySuggestion, };
@@ -12,14 +12,15 @@ export declare namespace ClientData {
12
12
  phone: string;
13
13
  address: string;
14
14
  city: string;
15
+ suburb: string;
15
16
  state: string;
16
17
  zip: string;
17
18
  country: string;
18
19
  linkedIn?: string;
19
- countryPhoneCode?: string;
20
+ countryPhoneCode: string;
20
21
  }
21
22
  const collection: () => string;
22
23
  const document: (clientDataId: string) => string;
23
24
  const formatClientData: (clientData: ClientData.Model) => string;
24
- const createNew: (firstName: string, lastName: string, email: string, phone: string, address: string, city: string, state: string, zip: string, country: string) => ClientData.Model;
25
+ const createNew: (firstName: string, lastName: string, email: string, phone: string, address: string, city: string, state: string, zip: string, country: string, countryPhoneCode: string, suburb: string) => ClientData.Model;
25
26
  }
@@ -5,7 +5,7 @@ export var ClientData;
5
5
  ClientData.formatClientData = (clientData) => {
6
6
  return `${clientData.firstName} ${clientData.lastName} (${clientData.email})`;
7
7
  };
8
- ClientData.createNew = (firstName, lastName, email, phone, address, city, state, zip, country) => {
8
+ ClientData.createNew = (firstName, lastName, email, phone, address, city, state, zip, country, countryPhoneCode, suburb) => {
9
9
  return {
10
10
  firstName,
11
11
  lastName,
@@ -15,9 +15,11 @@ export var ClientData;
15
15
  phone,
16
16
  address,
17
17
  city,
18
+ suburb,
18
19
  state,
19
20
  zip,
20
21
  country,
22
+ countryPhoneCode,
21
23
  createdAt: new Date().toISOString(),
22
24
  };
23
25
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobsearch-works/firestore-models",
3
- "version": "1.0.2",
3
+ "version": "1.0.7",
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",