@hasna/microservices 0.0.9 → 0.0.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 (100) hide show
  1. package/bin/index.js +236 -36
  2. package/bin/mcp.js +153 -4
  3. package/dist/index.js +120 -3
  4. package/microservices/microservice-analytics/package.json +27 -0
  5. package/microservices/microservice-analytics/src/cli/index.ts +373 -0
  6. package/microservices/microservice-analytics/src/db/analytics.ts +564 -0
  7. package/microservices/microservice-analytics/src/db/database.ts +93 -0
  8. package/microservices/microservice-analytics/src/db/migrations.ts +50 -0
  9. package/microservices/microservice-analytics/src/index.ts +37 -0
  10. package/microservices/microservice-analytics/src/mcp/index.ts +334 -0
  11. package/microservices/microservice-assets/package.json +27 -0
  12. package/microservices/microservice-assets/src/cli/index.ts +375 -0
  13. package/microservices/microservice-assets/src/db/assets.ts +370 -0
  14. package/microservices/microservice-assets/src/db/database.ts +93 -0
  15. package/microservices/microservice-assets/src/db/migrations.ts +51 -0
  16. package/microservices/microservice-assets/src/index.ts +32 -0
  17. package/microservices/microservice-assets/src/mcp/index.ts +346 -0
  18. package/microservices/microservice-compliance/package.json +27 -0
  19. package/microservices/microservice-compliance/src/cli/index.ts +467 -0
  20. package/microservices/microservice-compliance/src/db/compliance.ts +633 -0
  21. package/microservices/microservice-compliance/src/db/database.ts +93 -0
  22. package/microservices/microservice-compliance/src/db/migrations.ts +63 -0
  23. package/microservices/microservice-compliance/src/index.ts +46 -0
  24. package/microservices/microservice-compliance/src/mcp/index.ts +438 -0
  25. package/microservices/microservice-habits/package.json +27 -0
  26. package/microservices/microservice-habits/src/cli/index.ts +315 -0
  27. package/microservices/microservice-habits/src/db/database.ts +93 -0
  28. package/microservices/microservice-habits/src/db/habits.ts +451 -0
  29. package/microservices/microservice-habits/src/db/migrations.ts +46 -0
  30. package/microservices/microservice-habits/src/index.ts +31 -0
  31. package/microservices/microservice-habits/src/mcp/index.ts +313 -0
  32. package/microservices/microservice-health/package.json +27 -0
  33. package/microservices/microservice-health/src/cli/index.ts +484 -0
  34. package/microservices/microservice-health/src/db/database.ts +93 -0
  35. package/microservices/microservice-health/src/db/health.ts +708 -0
  36. package/microservices/microservice-health/src/db/migrations.ts +70 -0
  37. package/microservices/microservice-health/src/index.ts +63 -0
  38. package/microservices/microservice-health/src/mcp/index.ts +437 -0
  39. package/microservices/microservice-leads/package.json +27 -0
  40. package/microservices/microservice-leads/src/cli/index.ts +596 -0
  41. package/microservices/microservice-leads/src/db/database.ts +93 -0
  42. package/microservices/microservice-leads/src/db/leads.ts +520 -0
  43. package/microservices/microservice-leads/src/db/lists.ts +151 -0
  44. package/microservices/microservice-leads/src/db/migrations.ts +93 -0
  45. package/microservices/microservice-leads/src/index.ts +65 -0
  46. package/microservices/microservice-leads/src/lib/enrichment.ts +202 -0
  47. package/microservices/microservice-leads/src/lib/scoring.ts +134 -0
  48. package/microservices/microservice-leads/src/mcp/index.ts +533 -0
  49. package/microservices/microservice-notifications/package.json +27 -0
  50. package/microservices/microservice-notifications/src/cli/index.ts +349 -0
  51. package/microservices/microservice-notifications/src/db/database.ts +93 -0
  52. package/microservices/microservice-notifications/src/db/migrations.ts +62 -0
  53. package/microservices/microservice-notifications/src/db/notifications.ts +509 -0
  54. package/microservices/microservice-notifications/src/index.ts +41 -0
  55. package/microservices/microservice-notifications/src/mcp/index.ts +422 -0
  56. package/microservices/microservice-products/package.json +27 -0
  57. package/microservices/microservice-products/src/cli/index.ts +416 -0
  58. package/microservices/microservice-products/src/db/categories.ts +154 -0
  59. package/microservices/microservice-products/src/db/database.ts +93 -0
  60. package/microservices/microservice-products/src/db/migrations.ts +58 -0
  61. package/microservices/microservice-products/src/db/pricing-tiers.ts +66 -0
  62. package/microservices/microservice-products/src/db/products.ts +452 -0
  63. package/microservices/microservice-products/src/index.ts +53 -0
  64. package/microservices/microservice-products/src/mcp/index.ts +453 -0
  65. package/microservices/microservice-projects/package.json +27 -0
  66. package/microservices/microservice-projects/src/cli/index.ts +480 -0
  67. package/microservices/microservice-projects/src/db/database.ts +93 -0
  68. package/microservices/microservice-projects/src/db/migrations.ts +65 -0
  69. package/microservices/microservice-projects/src/db/projects.ts +715 -0
  70. package/microservices/microservice-projects/src/index.ts +57 -0
  71. package/microservices/microservice-projects/src/mcp/index.ts +501 -0
  72. package/microservices/microservice-proposals/package.json +27 -0
  73. package/microservices/microservice-proposals/src/cli/index.ts +400 -0
  74. package/microservices/microservice-proposals/src/db/database.ts +93 -0
  75. package/microservices/microservice-proposals/src/db/migrations.ts +52 -0
  76. package/microservices/microservice-proposals/src/db/proposals.ts +532 -0
  77. package/microservices/microservice-proposals/src/index.ts +37 -0
  78. package/microservices/microservice-proposals/src/mcp/index.ts +375 -0
  79. package/microservices/microservice-reading/package.json +27 -0
  80. package/microservices/microservice-reading/src/cli/index.ts +464 -0
  81. package/microservices/microservice-reading/src/db/database.ts +93 -0
  82. package/microservices/microservice-reading/src/db/migrations.ts +59 -0
  83. package/microservices/microservice-reading/src/db/reading.ts +524 -0
  84. package/microservices/microservice-reading/src/index.ts +51 -0
  85. package/microservices/microservice-reading/src/mcp/index.ts +368 -0
  86. package/microservices/microservice-travel/package.json +27 -0
  87. package/microservices/microservice-travel/src/cli/index.ts +505 -0
  88. package/microservices/microservice-travel/src/db/database.ts +93 -0
  89. package/microservices/microservice-travel/src/db/migrations.ts +77 -0
  90. package/microservices/microservice-travel/src/db/travel.ts +802 -0
  91. package/microservices/microservice-travel/src/index.ts +60 -0
  92. package/microservices/microservice-travel/src/mcp/index.ts +495 -0
  93. package/microservices/microservice-wiki/package.json +27 -0
  94. package/microservices/microservice-wiki/src/cli/index.ts +345 -0
  95. package/microservices/microservice-wiki/src/db/database.ts +93 -0
  96. package/microservices/microservice-wiki/src/db/migrations.ts +55 -0
  97. package/microservices/microservice-wiki/src/db/wiki.ts +395 -0
  98. package/microservices/microservice-wiki/src/index.ts +32 -0
  99. package/microservices/microservice-wiki/src/mcp/index.ts +344 -0
  100. package/package.json +1 -1
@@ -0,0 +1,451 @@
1
+ /**
2
+ * Habit CRUD operations, completions, streaks, and analytics
3
+ */
4
+
5
+ import { getDatabase } from "./database.js";
6
+
7
+ // --- Types ---
8
+
9
+ export interface Habit {
10
+ id: string;
11
+ name: string;
12
+ description: string | null;
13
+ frequency: "daily" | "weekly" | "monthly";
14
+ target_count: number;
15
+ category: string | null;
16
+ active: boolean;
17
+ created_at: string;
18
+ updated_at: string;
19
+ }
20
+
21
+ interface HabitRow {
22
+ id: string;
23
+ name: string;
24
+ description: string | null;
25
+ frequency: string;
26
+ target_count: number;
27
+ category: string | null;
28
+ active: number;
29
+ created_at: string;
30
+ updated_at: string;
31
+ }
32
+
33
+ export interface Completion {
34
+ id: string;
35
+ habit_id: string;
36
+ completed_at: string;
37
+ notes: string | null;
38
+ value: number | null;
39
+ }
40
+
41
+ export interface Streak {
42
+ habit_id: string;
43
+ current_streak: number;
44
+ longest_streak: number;
45
+ last_completed: string | null;
46
+ }
47
+
48
+ export interface TodayStatus {
49
+ habit: Habit;
50
+ completed_today: boolean;
51
+ }
52
+
53
+ export interface WeeklyReportEntry {
54
+ habit: Habit;
55
+ completions: number;
56
+ target: number;
57
+ rate: number;
58
+ }
59
+
60
+ // --- Helpers ---
61
+
62
+ function rowToHabit(row: HabitRow): Habit {
63
+ return {
64
+ ...row,
65
+ frequency: row.frequency as Habit["frequency"],
66
+ active: row.active === 1,
67
+ };
68
+ }
69
+
70
+ function todayDate(): string {
71
+ return new Date().toISOString().split("T")[0];
72
+ }
73
+
74
+ function startOfWeek(): string {
75
+ const now = new Date();
76
+ const day = now.getDay();
77
+ const diff = now.getDate() - day + (day === 0 ? -6 : 1); // Monday
78
+ const monday = new Date(now.setDate(diff));
79
+ return monday.toISOString().split("T")[0];
80
+ }
81
+
82
+ // --- CRUD ---
83
+
84
+ export interface CreateHabitInput {
85
+ name: string;
86
+ description?: string;
87
+ frequency?: "daily" | "weekly" | "monthly";
88
+ target_count?: number;
89
+ category?: string;
90
+ }
91
+
92
+ export function createHabit(input: CreateHabitInput): Habit {
93
+ const db = getDatabase();
94
+ const id = crypto.randomUUID();
95
+
96
+ db.prepare(
97
+ `INSERT INTO habits (id, name, description, frequency, target_count, category)
98
+ VALUES (?, ?, ?, ?, ?, ?)`
99
+ ).run(
100
+ id,
101
+ input.name,
102
+ input.description || null,
103
+ input.frequency || "daily",
104
+ input.target_count ?? 1,
105
+ input.category || null
106
+ );
107
+
108
+ // Initialize streak record
109
+ db.prepare(
110
+ `INSERT INTO streaks (habit_id, current_streak, longest_streak, last_completed)
111
+ VALUES (?, 0, 0, NULL)`
112
+ ).run(id);
113
+
114
+ return getHabit(id)!;
115
+ }
116
+
117
+ export function getHabit(id: string): Habit | null {
118
+ const db = getDatabase();
119
+ const row = db.prepare("SELECT * FROM habits WHERE id = ?").get(id) as HabitRow | null;
120
+ return row ? rowToHabit(row) : null;
121
+ }
122
+
123
+ export interface ListHabitsOptions {
124
+ category?: string;
125
+ active?: boolean;
126
+ frequency?: string;
127
+ limit?: number;
128
+ offset?: number;
129
+ }
130
+
131
+ export function listHabits(options: ListHabitsOptions = {}): Habit[] {
132
+ const db = getDatabase();
133
+ const conditions: string[] = [];
134
+ const params: unknown[] = [];
135
+
136
+ if (options.category) {
137
+ conditions.push("category = ?");
138
+ params.push(options.category);
139
+ }
140
+
141
+ if (options.active !== undefined) {
142
+ conditions.push("active = ?");
143
+ params.push(options.active ? 1 : 0);
144
+ }
145
+
146
+ if (options.frequency) {
147
+ conditions.push("frequency = ?");
148
+ params.push(options.frequency);
149
+ }
150
+
151
+ let sql = "SELECT * FROM habits";
152
+ if (conditions.length > 0) {
153
+ sql += " WHERE " + conditions.join(" AND ");
154
+ }
155
+ sql += " ORDER BY name";
156
+
157
+ if (options.limit) {
158
+ sql += " LIMIT ?";
159
+ params.push(options.limit);
160
+ }
161
+ if (options.offset) {
162
+ sql += " OFFSET ?";
163
+ params.push(options.offset);
164
+ }
165
+
166
+ const rows = db.prepare(sql).all(...params) as HabitRow[];
167
+ return rows.map(rowToHabit);
168
+ }
169
+
170
+ export interface UpdateHabitInput {
171
+ name?: string;
172
+ description?: string;
173
+ frequency?: "daily" | "weekly" | "monthly";
174
+ target_count?: number;
175
+ category?: string;
176
+ }
177
+
178
+ export function updateHabit(id: string, input: UpdateHabitInput): Habit | null {
179
+ const db = getDatabase();
180
+ const existing = getHabit(id);
181
+ if (!existing) return null;
182
+
183
+ const sets: string[] = [];
184
+ const params: unknown[] = [];
185
+
186
+ if (input.name !== undefined) {
187
+ sets.push("name = ?");
188
+ params.push(input.name);
189
+ }
190
+ if (input.description !== undefined) {
191
+ sets.push("description = ?");
192
+ params.push(input.description);
193
+ }
194
+ if (input.frequency !== undefined) {
195
+ sets.push("frequency = ?");
196
+ params.push(input.frequency);
197
+ }
198
+ if (input.target_count !== undefined) {
199
+ sets.push("target_count = ?");
200
+ params.push(input.target_count);
201
+ }
202
+ if (input.category !== undefined) {
203
+ sets.push("category = ?");
204
+ params.push(input.category);
205
+ }
206
+
207
+ if (sets.length === 0) return existing;
208
+
209
+ sets.push("updated_at = datetime('now')");
210
+ params.push(id);
211
+
212
+ db.prepare(
213
+ `UPDATE habits SET ${sets.join(", ")} WHERE id = ?`
214
+ ).run(...params);
215
+
216
+ return getHabit(id);
217
+ }
218
+
219
+ export function deleteHabit(id: string): boolean {
220
+ const db = getDatabase();
221
+ const result = db.prepare("DELETE FROM habits WHERE id = ?").run(id);
222
+ return result.changes > 0;
223
+ }
224
+
225
+ export function activateHabit(id: string): Habit | null {
226
+ const db = getDatabase();
227
+ const existing = getHabit(id);
228
+ if (!existing) return null;
229
+
230
+ db.prepare("UPDATE habits SET active = 1, updated_at = datetime('now') WHERE id = ?").run(id);
231
+ return getHabit(id);
232
+ }
233
+
234
+ export function deactivateHabit(id: string): Habit | null {
235
+ const db = getDatabase();
236
+ const existing = getHabit(id);
237
+ if (!existing) return null;
238
+
239
+ db.prepare("UPDATE habits SET active = 0, updated_at = datetime('now') WHERE id = ?").run(id);
240
+ return getHabit(id);
241
+ }
242
+
243
+ // --- Completions ---
244
+
245
+ export function completeHabit(
246
+ habitId: string,
247
+ notes?: string,
248
+ value?: number
249
+ ): Completion | null {
250
+ const db = getDatabase();
251
+ const habit = getHabit(habitId);
252
+ if (!habit) return null;
253
+
254
+ const id = crypto.randomUUID();
255
+ const now = new Date().toISOString();
256
+
257
+ db.prepare(
258
+ `INSERT INTO completions (id, habit_id, completed_at, notes, value)
259
+ VALUES (?, ?, ?, ?, ?)`
260
+ ).run(id, habitId, now, notes || null, value ?? null);
261
+
262
+ // Update streak
263
+ updateStreak(habitId, now);
264
+
265
+ return {
266
+ id,
267
+ habit_id: habitId,
268
+ completed_at: now,
269
+ notes: notes || null,
270
+ value: value ?? null,
271
+ };
272
+ }
273
+
274
+ function updateStreak(habitId: string, completedAt: string): void {
275
+ const db = getDatabase();
276
+
277
+ const streak = db.prepare("SELECT * FROM streaks WHERE habit_id = ?").get(habitId) as Streak | null;
278
+
279
+ const today = completedAt.split("T")[0];
280
+
281
+ if (!streak) {
282
+ // First completion ever
283
+ db.prepare(
284
+ `INSERT INTO streaks (habit_id, current_streak, longest_streak, last_completed)
285
+ VALUES (?, 1, 1, ?)`
286
+ ).run(habitId, today);
287
+ return;
288
+ }
289
+
290
+ const lastCompleted = streak.last_completed;
291
+
292
+ if (!lastCompleted) {
293
+ // No previous completion
294
+ db.prepare(
295
+ `UPDATE streaks SET current_streak = 1, longest_streak = MAX(longest_streak, 1), last_completed = ? WHERE habit_id = ?`
296
+ ).run(today, habitId);
297
+ return;
298
+ }
299
+
300
+ // Check if already completed today
301
+ if (lastCompleted === today) {
302
+ return; // Streak doesn't change for same-day completions
303
+ }
304
+
305
+ // Check if this is a consecutive day
306
+ const lastDate = new Date(lastCompleted + "T00:00:00Z");
307
+ const todayDate = new Date(today + "T00:00:00Z");
308
+ const diffDays = Math.floor(
309
+ (todayDate.getTime() - lastDate.getTime()) / (1000 * 60 * 60 * 24)
310
+ );
311
+
312
+ if (diffDays === 1) {
313
+ // Consecutive day — increment streak
314
+ const newStreak = streak.current_streak + 1;
315
+ const newLongest = Math.max(streak.longest_streak, newStreak);
316
+ db.prepare(
317
+ `UPDATE streaks SET current_streak = ?, longest_streak = ?, last_completed = ? WHERE habit_id = ?`
318
+ ).run(newStreak, newLongest, today, habitId);
319
+ } else {
320
+ // Streak broken — reset to 1
321
+ const newLongest = Math.max(streak.longest_streak, 1);
322
+ db.prepare(
323
+ `UPDATE streaks SET current_streak = 1, longest_streak = ?, last_completed = ? WHERE habit_id = ?`
324
+ ).run(newLongest, today, habitId);
325
+ }
326
+ }
327
+
328
+ export function getCompletions(habitId: string, limit?: number): Completion[] {
329
+ const db = getDatabase();
330
+ let sql = "SELECT * FROM completions WHERE habit_id = ? ORDER BY completed_at DESC";
331
+ const params: unknown[] = [habitId];
332
+
333
+ if (limit) {
334
+ sql += " LIMIT ?";
335
+ params.push(limit);
336
+ }
337
+
338
+ return db.prepare(sql).all(...params) as Completion[];
339
+ }
340
+
341
+ // --- Streaks ---
342
+
343
+ export function getStreak(habitId: string): Streak | null {
344
+ const db = getDatabase();
345
+ return db.prepare("SELECT * FROM streaks WHERE habit_id = ?").get(habitId) as Streak | null;
346
+ }
347
+
348
+ export function getAllStreaks(): Streak[] {
349
+ const db = getDatabase();
350
+ return db.prepare(
351
+ "SELECT s.* FROM streaks s JOIN habits h ON s.habit_id = h.id WHERE h.active = 1 ORDER BY s.current_streak DESC"
352
+ ).all() as Streak[];
353
+ }
354
+
355
+ // --- Analytics ---
356
+
357
+ export function getCompletionRate(habitId: string, days: number): number {
358
+ const db = getDatabase();
359
+ const habit = getHabit(habitId);
360
+ if (!habit) return 0;
361
+
362
+ const sinceDate = new Date();
363
+ sinceDate.setDate(sinceDate.getDate() - days);
364
+ const since = sinceDate.toISOString();
365
+
366
+ const row = db
367
+ .prepare(
368
+ "SELECT COUNT(*) as count FROM completions WHERE habit_id = ? AND completed_at >= ?"
369
+ )
370
+ .get(habitId, since) as { count: number };
371
+
372
+ // For daily habits: target = days * target_count
373
+ // For weekly: target = (days / 7) * target_count
374
+ // For monthly: target = (days / 30) * target_count
375
+ let target: number;
376
+ switch (habit.frequency) {
377
+ case "daily":
378
+ target = days * habit.target_count;
379
+ break;
380
+ case "weekly":
381
+ target = Math.max(1, Math.floor(days / 7)) * habit.target_count;
382
+ break;
383
+ case "monthly":
384
+ target = Math.max(1, Math.floor(days / 30)) * habit.target_count;
385
+ break;
386
+ }
387
+
388
+ return Math.min(100, Math.round((row.count / target) * 100));
389
+ }
390
+
391
+ export function getTodayStatus(): TodayStatus[] {
392
+ const db = getDatabase();
393
+ const habits = listHabits({ active: true });
394
+ const today = todayDate();
395
+ const todayStart = today + "T00:00:00";
396
+ const todayEnd = today + "T23:59:59";
397
+
398
+ return habits.map((habit) => {
399
+ const row = db
400
+ .prepare(
401
+ "SELECT COUNT(*) as count FROM completions WHERE habit_id = ? AND completed_at >= ? AND completed_at <= ?"
402
+ )
403
+ .get(habit.id, todayStart, todayEnd) as { count: number };
404
+
405
+ return {
406
+ habit,
407
+ completed_today: row.count >= habit.target_count,
408
+ };
409
+ });
410
+ }
411
+
412
+ export function getWeeklyReport(): WeeklyReportEntry[] {
413
+ const db = getDatabase();
414
+ const habits = listHabits({ active: true });
415
+ const weekStart = startOfWeek();
416
+ const weekStartDatetime = weekStart + "T00:00:00";
417
+
418
+ return habits.map((habit) => {
419
+ const row = db
420
+ .prepare(
421
+ "SELECT COUNT(*) as count FROM completions WHERE habit_id = ? AND completed_at >= ?"
422
+ )
423
+ .get(habit.id, weekStartDatetime) as { count: number };
424
+
425
+ let target: number;
426
+ switch (habit.frequency) {
427
+ case "daily":
428
+ target = 7 * habit.target_count;
429
+ break;
430
+ case "weekly":
431
+ target = habit.target_count;
432
+ break;
433
+ case "monthly":
434
+ target = Math.max(1, Math.round(habit.target_count / 4));
435
+ break;
436
+ }
437
+
438
+ return {
439
+ habit,
440
+ completions: row.count,
441
+ target,
442
+ rate: Math.min(100, Math.round((row.count / target) * 100)),
443
+ };
444
+ });
445
+ }
446
+
447
+ export function countHabits(): number {
448
+ const db = getDatabase();
449
+ const row = db.prepare("SELECT COUNT(*) as count FROM habits").get() as { count: number };
450
+ return row.count;
451
+ }
@@ -0,0 +1,46 @@
1
+ export interface MigrationEntry {
2
+ id: number;
3
+ name: string;
4
+ sql: string;
5
+ }
6
+
7
+ export const MIGRATIONS: MigrationEntry[] = [
8
+ {
9
+ id: 1,
10
+ name: "initial_schema",
11
+ sql: `
12
+ CREATE TABLE IF NOT EXISTS habits (
13
+ id TEXT PRIMARY KEY,
14
+ name TEXT NOT NULL,
15
+ description TEXT,
16
+ frequency TEXT NOT NULL DEFAULT 'daily' CHECK(frequency IN ('daily', 'weekly', 'monthly')),
17
+ target_count INTEGER NOT NULL DEFAULT 1,
18
+ category TEXT,
19
+ active INTEGER NOT NULL DEFAULT 1,
20
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
21
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
22
+ );
23
+
24
+ CREATE TABLE IF NOT EXISTS completions (
25
+ id TEXT PRIMARY KEY,
26
+ habit_id TEXT NOT NULL REFERENCES habits(id) ON DELETE CASCADE,
27
+ completed_at TEXT NOT NULL DEFAULT (datetime('now')),
28
+ notes TEXT,
29
+ value REAL
30
+ );
31
+
32
+ CREATE TABLE IF NOT EXISTS streaks (
33
+ habit_id TEXT PRIMARY KEY REFERENCES habits(id) ON DELETE CASCADE,
34
+ current_streak INTEGER NOT NULL DEFAULT 0,
35
+ longest_streak INTEGER NOT NULL DEFAULT 0,
36
+ last_completed TEXT
37
+ );
38
+
39
+ CREATE INDEX IF NOT EXISTS idx_habits_category ON habits(category);
40
+ CREATE INDEX IF NOT EXISTS idx_habits_active ON habits(active);
41
+ CREATE INDEX IF NOT EXISTS idx_habits_frequency ON habits(frequency);
42
+ CREATE INDEX IF NOT EXISTS idx_completions_habit ON completions(habit_id);
43
+ CREATE INDEX IF NOT EXISTS idx_completions_date ON completions(completed_at);
44
+ `,
45
+ },
46
+ ];
@@ -0,0 +1,31 @@
1
+ /**
2
+ * microservice-habits — Habit tracking microservice
3
+ */
4
+
5
+ export {
6
+ createHabit,
7
+ getHabit,
8
+ listHabits,
9
+ updateHabit,
10
+ deleteHabit,
11
+ activateHabit,
12
+ deactivateHabit,
13
+ completeHabit,
14
+ getCompletions,
15
+ getStreak,
16
+ getAllStreaks,
17
+ getCompletionRate,
18
+ getTodayStatus,
19
+ getWeeklyReport,
20
+ countHabits,
21
+ type Habit,
22
+ type Completion,
23
+ type Streak,
24
+ type TodayStatus,
25
+ type WeeklyReportEntry,
26
+ type CreateHabitInput,
27
+ type UpdateHabitInput,
28
+ type ListHabitsOptions,
29
+ } from "./db/habits.js";
30
+
31
+ export { getDatabase, closeDatabase } from "./db/database.js";