@hasna/microservices 0.0.3 → 0.0.4

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 (67) hide show
  1. package/bin/index.js +63 -0
  2. package/bin/mcp.js +63 -0
  3. package/dist/index.js +63 -0
  4. package/microservices/microservice-ads/package.json +27 -0
  5. package/microservices/microservice-ads/src/cli/index.ts +407 -0
  6. package/microservices/microservice-ads/src/db/campaigns.ts +493 -0
  7. package/microservices/microservice-ads/src/db/database.ts +93 -0
  8. package/microservices/microservice-ads/src/db/migrations.ts +60 -0
  9. package/microservices/microservice-ads/src/index.ts +39 -0
  10. package/microservices/microservice-ads/src/mcp/index.ts +320 -0
  11. package/microservices/microservice-contracts/package.json +27 -0
  12. package/microservices/microservice-contracts/src/cli/index.ts +383 -0
  13. package/microservices/microservice-contracts/src/db/contracts.ts +496 -0
  14. package/microservices/microservice-contracts/src/db/database.ts +93 -0
  15. package/microservices/microservice-contracts/src/db/migrations.ts +58 -0
  16. package/microservices/microservice-contracts/src/index.ts +43 -0
  17. package/microservices/microservice-contracts/src/mcp/index.ts +308 -0
  18. package/microservices/microservice-domains/package.json +27 -0
  19. package/microservices/microservice-domains/src/cli/index.ts +438 -0
  20. package/microservices/microservice-domains/src/db/database.ts +93 -0
  21. package/microservices/microservice-domains/src/db/domains.ts +551 -0
  22. package/microservices/microservice-domains/src/db/migrations.ts +60 -0
  23. package/microservices/microservice-domains/src/index.ts +44 -0
  24. package/microservices/microservice-domains/src/mcp/index.ts +368 -0
  25. package/microservices/microservice-hiring/package.json +27 -0
  26. package/microservices/microservice-hiring/src/cli/index.ts +431 -0
  27. package/microservices/microservice-hiring/src/db/database.ts +93 -0
  28. package/microservices/microservice-hiring/src/db/hiring.ts +582 -0
  29. package/microservices/microservice-hiring/src/db/migrations.ts +68 -0
  30. package/microservices/microservice-hiring/src/index.ts +51 -0
  31. package/microservices/microservice-hiring/src/mcp/index.ts +464 -0
  32. package/microservices/microservice-payments/package.json +27 -0
  33. package/microservices/microservice-payments/src/cli/index.ts +357 -0
  34. package/microservices/microservice-payments/src/db/database.ts +93 -0
  35. package/microservices/microservice-payments/src/db/migrations.ts +63 -0
  36. package/microservices/microservice-payments/src/db/payments.ts +652 -0
  37. package/microservices/microservice-payments/src/index.ts +51 -0
  38. package/microservices/microservice-payments/src/mcp/index.ts +460 -0
  39. package/microservices/microservice-payroll/package.json +27 -0
  40. package/microservices/microservice-payroll/src/cli/index.ts +374 -0
  41. package/microservices/microservice-payroll/src/db/database.ts +93 -0
  42. package/microservices/microservice-payroll/src/db/migrations.ts +69 -0
  43. package/microservices/microservice-payroll/src/db/payroll.ts +741 -0
  44. package/microservices/microservice-payroll/src/index.ts +48 -0
  45. package/microservices/microservice-payroll/src/mcp/index.ts +420 -0
  46. package/microservices/microservice-shipping/package.json +27 -0
  47. package/microservices/microservice-shipping/src/cli/index.ts +398 -0
  48. package/microservices/microservice-shipping/src/db/database.ts +93 -0
  49. package/microservices/microservice-shipping/src/db/migrations.ts +61 -0
  50. package/microservices/microservice-shipping/src/db/shipping.ts +643 -0
  51. package/microservices/microservice-shipping/src/index.ts +53 -0
  52. package/microservices/microservice-shipping/src/mcp/index.ts +385 -0
  53. package/microservices/microservice-social/package.json +27 -0
  54. package/microservices/microservice-social/src/cli/index.ts +447 -0
  55. package/microservices/microservice-social/src/db/database.ts +93 -0
  56. package/microservices/microservice-social/src/db/migrations.ts +55 -0
  57. package/microservices/microservice-social/src/db/social.ts +672 -0
  58. package/microservices/microservice-social/src/index.ts +46 -0
  59. package/microservices/microservice-social/src/mcp/index.ts +435 -0
  60. package/microservices/microservice-subscriptions/package.json +27 -0
  61. package/microservices/microservice-subscriptions/src/cli/index.ts +400 -0
  62. package/microservices/microservice-subscriptions/src/db/database.ts +93 -0
  63. package/microservices/microservice-subscriptions/src/db/migrations.ts +57 -0
  64. package/microservices/microservice-subscriptions/src/db/subscriptions.ts +692 -0
  65. package/microservices/microservice-subscriptions/src/index.ts +41 -0
  66. package/microservices/microservice-subscriptions/src/mcp/index.ts +365 -0
  67. package/package.json +1 -1
@@ -0,0 +1,407 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { Command } from "commander";
4
+ import {
5
+ createCampaign,
6
+ getCampaign,
7
+ listCampaigns,
8
+ updateCampaign,
9
+ deleteCampaign,
10
+ pauseCampaign,
11
+ resumeCampaign,
12
+ getCampaignStats,
13
+ getSpendByPlatform,
14
+ getPlatforms,
15
+ } from "../db/campaigns.js";
16
+ import {
17
+ createAdGroup,
18
+ listAdGroups,
19
+ } from "../db/campaigns.js";
20
+ import {
21
+ createAd,
22
+ listAds,
23
+ } from "../db/campaigns.js";
24
+
25
+ const program = new Command();
26
+
27
+ program
28
+ .name("microservice-ads")
29
+ .description("Ad campaign management microservice")
30
+ .version("0.0.1");
31
+
32
+ // --- Campaigns ---
33
+
34
+ const campaignCmd = program
35
+ .command("campaign")
36
+ .description("Campaign management");
37
+
38
+ campaignCmd
39
+ .command("create")
40
+ .description("Create a new campaign")
41
+ .requiredOption("--platform <platform>", "Platform (google/meta/linkedin/tiktok)")
42
+ .requiredOption("--name <name>", "Campaign name")
43
+ .option("--status <status>", "Status (draft/active/paused/completed)", "draft")
44
+ .option("--budget-daily <amount>", "Daily budget")
45
+ .option("--budget-total <amount>", "Total budget")
46
+ .option("--start-date <date>", "Start date (YYYY-MM-DD)")
47
+ .option("--end-date <date>", "End date (YYYY-MM-DD)")
48
+ .option("--json", "Output as JSON", false)
49
+ .action((opts) => {
50
+ const campaign = createCampaign({
51
+ platform: opts.platform,
52
+ name: opts.name,
53
+ status: opts.status,
54
+ budget_daily: opts.budgetDaily ? parseFloat(opts.budgetDaily) : undefined,
55
+ budget_total: opts.budgetTotal ? parseFloat(opts.budgetTotal) : undefined,
56
+ start_date: opts.startDate,
57
+ end_date: opts.endDate,
58
+ });
59
+
60
+ if (opts.json) {
61
+ console.log(JSON.stringify(campaign, null, 2));
62
+ } else {
63
+ console.log(`Created campaign: ${campaign.name} [${campaign.platform}] (${campaign.id})`);
64
+ }
65
+ });
66
+
67
+ campaignCmd
68
+ .command("list")
69
+ .description("List campaigns")
70
+ .option("--platform <platform>", "Filter by platform")
71
+ .option("--status <status>", "Filter by status")
72
+ .option("--search <query>", "Search by name")
73
+ .option("--limit <n>", "Limit results")
74
+ .option("--json", "Output as JSON", false)
75
+ .action((opts) => {
76
+ const campaigns = listCampaigns({
77
+ platform: opts.platform,
78
+ status: opts.status,
79
+ search: opts.search,
80
+ limit: opts.limit ? parseInt(opts.limit) : undefined,
81
+ });
82
+
83
+ if (opts.json) {
84
+ console.log(JSON.stringify(campaigns, null, 2));
85
+ } else {
86
+ if (campaigns.length === 0) {
87
+ console.log("No campaigns found.");
88
+ return;
89
+ }
90
+ for (const c of campaigns) {
91
+ const budget = c.budget_total > 0 ? ` $${c.budget_total}` : "";
92
+ console.log(` [${c.platform}] ${c.name} (${c.status})${budget}`);
93
+ }
94
+ console.log(`\n${campaigns.length} campaign(s)`);
95
+ }
96
+ });
97
+
98
+ campaignCmd
99
+ .command("get")
100
+ .description("Get a campaign by ID")
101
+ .argument("<id>", "Campaign ID")
102
+ .option("--json", "Output as JSON", false)
103
+ .action((id, opts) => {
104
+ const campaign = getCampaign(id);
105
+ if (!campaign) {
106
+ console.error(`Campaign '${id}' not found.`);
107
+ process.exit(1);
108
+ }
109
+
110
+ if (opts.json) {
111
+ console.log(JSON.stringify(campaign, null, 2));
112
+ } else {
113
+ console.log(`${campaign.name} [${campaign.platform}]`);
114
+ console.log(` Status: ${campaign.status}`);
115
+ console.log(` Budget: $${campaign.budget_daily}/day, $${campaign.budget_total} total`);
116
+ console.log(` Spend: $${campaign.spend}`);
117
+ console.log(` Impressions: ${campaign.impressions}, Clicks: ${campaign.clicks}, Conversions: ${campaign.conversions}`);
118
+ console.log(` ROAS: ${campaign.roas}`);
119
+ if (campaign.start_date) console.log(` Start: ${campaign.start_date}`);
120
+ if (campaign.end_date) console.log(` End: ${campaign.end_date}`);
121
+ }
122
+ });
123
+
124
+ campaignCmd
125
+ .command("update")
126
+ .description("Update a campaign")
127
+ .argument("<id>", "Campaign ID")
128
+ .option("--platform <platform>", "Platform")
129
+ .option("--name <name>", "Campaign name")
130
+ .option("--status <status>", "Status")
131
+ .option("--budget-daily <amount>", "Daily budget")
132
+ .option("--budget-total <amount>", "Total budget")
133
+ .option("--spend <amount>", "Total spend")
134
+ .option("--impressions <n>", "Impressions")
135
+ .option("--clicks <n>", "Clicks")
136
+ .option("--conversions <n>", "Conversions")
137
+ .option("--roas <n>", "ROAS")
138
+ .option("--start-date <date>", "Start date")
139
+ .option("--end-date <date>", "End date")
140
+ .option("--json", "Output as JSON", false)
141
+ .action((id, opts) => {
142
+ const input: Record<string, unknown> = {};
143
+ if (opts.platform !== undefined) input.platform = opts.platform;
144
+ if (opts.name !== undefined) input.name = opts.name;
145
+ if (opts.status !== undefined) input.status = opts.status;
146
+ if (opts.budgetDaily !== undefined) input.budget_daily = parseFloat(opts.budgetDaily);
147
+ if (opts.budgetTotal !== undefined) input.budget_total = parseFloat(opts.budgetTotal);
148
+ if (opts.spend !== undefined) input.spend = parseFloat(opts.spend);
149
+ if (opts.impressions !== undefined) input.impressions = parseInt(opts.impressions);
150
+ if (opts.clicks !== undefined) input.clicks = parseInt(opts.clicks);
151
+ if (opts.conversions !== undefined) input.conversions = parseInt(opts.conversions);
152
+ if (opts.roas !== undefined) input.roas = parseFloat(opts.roas);
153
+ if (opts.startDate !== undefined) input.start_date = opts.startDate;
154
+ if (opts.endDate !== undefined) input.end_date = opts.endDate;
155
+
156
+ const campaign = updateCampaign(id, input);
157
+ if (!campaign) {
158
+ console.error(`Campaign '${id}' not found.`);
159
+ process.exit(1);
160
+ }
161
+
162
+ if (opts.json) {
163
+ console.log(JSON.stringify(campaign, null, 2));
164
+ } else {
165
+ console.log(`Updated: ${campaign.name} [${campaign.platform}]`);
166
+ }
167
+ });
168
+
169
+ campaignCmd
170
+ .command("delete")
171
+ .description("Delete a campaign")
172
+ .argument("<id>", "Campaign ID")
173
+ .action((id) => {
174
+ const deleted = deleteCampaign(id);
175
+ if (deleted) {
176
+ console.log(`Deleted campaign ${id}`);
177
+ } else {
178
+ console.error(`Campaign '${id}' not found.`);
179
+ process.exit(1);
180
+ }
181
+ });
182
+
183
+ campaignCmd
184
+ .command("pause")
185
+ .description("Pause a campaign")
186
+ .argument("<id>", "Campaign ID")
187
+ .option("--json", "Output as JSON", false)
188
+ .action((id, opts) => {
189
+ const campaign = pauseCampaign(id);
190
+ if (!campaign) {
191
+ console.error(`Campaign '${id}' not found.`);
192
+ process.exit(1);
193
+ }
194
+
195
+ if (opts.json) {
196
+ console.log(JSON.stringify(campaign, null, 2));
197
+ } else {
198
+ console.log(`Paused: ${campaign.name}`);
199
+ }
200
+ });
201
+
202
+ campaignCmd
203
+ .command("resume")
204
+ .description("Resume a paused campaign")
205
+ .argument("<id>", "Campaign ID")
206
+ .option("--json", "Output as JSON", false)
207
+ .action((id, opts) => {
208
+ const campaign = resumeCampaign(id);
209
+ if (!campaign) {
210
+ console.error(`Campaign '${id}' not found.`);
211
+ process.exit(1);
212
+ }
213
+
214
+ if (opts.json) {
215
+ console.log(JSON.stringify(campaign, null, 2));
216
+ } else {
217
+ console.log(`Resumed: ${campaign.name}`);
218
+ }
219
+ });
220
+
221
+ // --- Ad Groups ---
222
+
223
+ const adGroupCmd = program
224
+ .command("ad-group")
225
+ .description("Ad group management");
226
+
227
+ adGroupCmd
228
+ .command("create")
229
+ .description("Create a new ad group")
230
+ .requiredOption("--campaign <id>", "Campaign ID")
231
+ .requiredOption("--name <name>", "Ad group name")
232
+ .option("--targeting <json>", "Targeting JSON")
233
+ .option("--status <status>", "Status", "draft")
234
+ .option("--json", "Output as JSON", false)
235
+ .action((opts) => {
236
+ const adGroup = createAdGroup({
237
+ campaign_id: opts.campaign,
238
+ name: opts.name,
239
+ targeting: opts.targeting ? JSON.parse(opts.targeting) : undefined,
240
+ status: opts.status,
241
+ });
242
+
243
+ if (opts.json) {
244
+ console.log(JSON.stringify(adGroup, null, 2));
245
+ } else {
246
+ console.log(`Created ad group: ${adGroup.name} (${adGroup.id})`);
247
+ }
248
+ });
249
+
250
+ adGroupCmd
251
+ .command("list")
252
+ .description("List ad groups")
253
+ .option("--campaign <id>", "Filter by campaign ID")
254
+ .option("--json", "Output as JSON", false)
255
+ .action((opts) => {
256
+ const adGroups = listAdGroups(opts.campaign);
257
+
258
+ if (opts.json) {
259
+ console.log(JSON.stringify(adGroups, null, 2));
260
+ } else {
261
+ if (adGroups.length === 0) {
262
+ console.log("No ad groups found.");
263
+ return;
264
+ }
265
+ for (const ag of adGroups) {
266
+ console.log(` ${ag.name} (${ag.status}) — campaign: ${ag.campaign_id}`);
267
+ }
268
+ console.log(`\n${adGroups.length} ad group(s)`);
269
+ }
270
+ });
271
+
272
+ // --- Ads ---
273
+
274
+ const adCmd = program
275
+ .command("ad")
276
+ .description("Ad management");
277
+
278
+ adCmd
279
+ .command("create")
280
+ .description("Create a new ad")
281
+ .requiredOption("--ad-group <id>", "Ad group ID")
282
+ .requiredOption("--headline <text>", "Ad headline")
283
+ .option("--description <text>", "Ad description")
284
+ .option("--creative-url <url>", "Creative URL")
285
+ .option("--status <status>", "Status", "draft")
286
+ .option("--json", "Output as JSON", false)
287
+ .action((opts) => {
288
+ const ad = createAd({
289
+ ad_group_id: opts.adGroup,
290
+ headline: opts.headline,
291
+ description: opts.description,
292
+ creative_url: opts.creativeUrl,
293
+ status: opts.status,
294
+ });
295
+
296
+ if (opts.json) {
297
+ console.log(JSON.stringify(ad, null, 2));
298
+ } else {
299
+ console.log(`Created ad: ${ad.headline} (${ad.id})`);
300
+ }
301
+ });
302
+
303
+ adCmd
304
+ .command("list")
305
+ .description("List ads")
306
+ .option("--ad-group <id>", "Filter by ad group ID")
307
+ .option("--json", "Output as JSON", false)
308
+ .action((opts) => {
309
+ const ads = listAds(opts.adGroup);
310
+
311
+ if (opts.json) {
312
+ console.log(JSON.stringify(ads, null, 2));
313
+ } else {
314
+ if (ads.length === 0) {
315
+ console.log("No ads found.");
316
+ return;
317
+ }
318
+ for (const a of ads) {
319
+ console.log(` ${a.headline} (${a.status})`);
320
+ }
321
+ console.log(`\n${ads.length} ad(s)`);
322
+ }
323
+ });
324
+
325
+ // --- Stats & Reports ---
326
+
327
+ program
328
+ .command("stats")
329
+ .description("Show campaign statistics")
330
+ .option("--json", "Output as JSON", false)
331
+ .action((opts) => {
332
+ const stats = getCampaignStats();
333
+
334
+ if (opts.json) {
335
+ console.log(JSON.stringify(stats, null, 2));
336
+ } else {
337
+ console.log("Campaign Statistics:");
338
+ console.log(` Total campaigns: ${stats.total_campaigns}`);
339
+ console.log(` Active campaigns: ${stats.active_campaigns}`);
340
+ console.log(` Total spend: $${stats.total_spend.toFixed(2)}`);
341
+ console.log(` Total impressions: ${stats.total_impressions}`);
342
+ console.log(` Total clicks: ${stats.total_clicks}`);
343
+ console.log(` Total conversions: ${stats.total_conversions}`);
344
+ console.log(` Avg ROAS: ${stats.avg_roas.toFixed(2)}`);
345
+ }
346
+ });
347
+
348
+ program
349
+ .command("spend")
350
+ .description("Show spend by platform")
351
+ .option("--json", "Output as JSON", false)
352
+ .action((opts) => {
353
+ const spend = getSpendByPlatform();
354
+
355
+ if (opts.json) {
356
+ console.log(JSON.stringify(spend, null, 2));
357
+ } else {
358
+ if (spend.length === 0) {
359
+ console.log("No spend data.");
360
+ return;
361
+ }
362
+ console.log("Spend by Platform:");
363
+ for (const s of spend) {
364
+ console.log(` ${s.platform}: $${s.total_spend.toFixed(2)} (${s.campaign_count} campaigns)`);
365
+ }
366
+ }
367
+ });
368
+
369
+ program
370
+ .command("platforms")
371
+ .description("List platforms with campaigns")
372
+ .option("--json", "Output as JSON", false)
373
+ .action((opts) => {
374
+ const platforms = getPlatforms();
375
+
376
+ if (opts.json) {
377
+ console.log(JSON.stringify(platforms, null, 2));
378
+ } else {
379
+ if (platforms.length === 0) {
380
+ console.log("No platforms found.");
381
+ return;
382
+ }
383
+ console.log("Platforms:");
384
+ for (const p of platforms) {
385
+ console.log(` ${p}`);
386
+ }
387
+ }
388
+ });
389
+
390
+ program
391
+ .command("providers")
392
+ .description("List supported ad providers")
393
+ .option("--json", "Output as JSON", false)
394
+ .action((opts) => {
395
+ const providers = ["google", "meta", "linkedin", "tiktok"];
396
+
397
+ if (opts.json) {
398
+ console.log(JSON.stringify(providers, null, 2));
399
+ } else {
400
+ console.log("Supported Ad Providers:");
401
+ for (const p of providers) {
402
+ console.log(` ${p}`);
403
+ }
404
+ }
405
+ });
406
+
407
+ program.parse(process.argv);