@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 +258 -10
- package/dist/index.d.ts +10 -9
- package/dist/index.js +10 -9
- package/dist/models/clientData.d.ts +3 -2
- package/dist/models/clientData.js +3 -1
- package/package.json +1 -1
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
|
277
|
+
Import the models and their utilities in your application:
|
30
278
|
|
31
279
|
```typescript
|
32
|
-
import {
|
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
|
35
|
-
const
|
36
|
-
|
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
|
42
|
-
const
|
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
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
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