Skip to content

Commit e43e446

Browse files
authored
Merge pull request #723 from sparrowapp-dev/development
Release Version 2.28.1 [Merging development into prod]
2 parents 3172ceb + b98a7c8 commit e43e446

39 files changed

+1966
-136
lines changed

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ ENCRYPTION_SECRET= # Encryption key for LLM key's Encryption
9595
DEEPSEEK_ENDPOINT= # Deepseek API endpoint
9696
DEEPSEEK_API_KEY= # Deepseek API authentication key
9797
DEEPSEEK_API_VERSION= # Deepseek API version
98+
DEEPSEEK_API_MODEL= # Deepseek Model
9899

99100
# [HUBSPOT INTEGRATION]
100101
HUBSPOT_BASEURL= # HubSpot API base URL

deploymentManifests/deployment.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,11 @@ spec:
336336
secretKeyRef:
337337
name: sparrow-api-secret
338338
key: DEEPSEEK_API_VERSION
339+
- name: DEEPSEEK_API_MODEL
340+
valueFrom:
341+
secretKeyRef:
342+
name: sparrow-api-secret
343+
key: DEEPSEEK_API_MODEL
339344
- name: DB_NAME
340345
valueFrom:
341346
secretKeyRef:

deploymentManifests/release-v2.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,11 @@ spec:
305305
secretKeyRef:
306306
name: release-api-v2-secret
307307
key: DEEPSEEK_API_VERSION
308+
- name: DEEPSEEK_API_MODEL
309+
valueFrom:
310+
secretKeyRef:
311+
name: release-api-v2-secret
312+
key: DEEPSEEK_API_MODEL
308313
- name: DB_NAME
309314
valueFrom:
310315
secretKeyRef:
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Injectable, OnModuleInit, Inject } from "@nestjs/common";
2+
import { Collections } from "@src/modules/common/enum/database.collection.enum";
3+
import { Db } from "mongodb";
4+
5+
@Injectable()
6+
export class CreateSuperadminMigration implements OnModuleInit {
7+
private hasRun = false;
8+
constructor(
9+
@Inject("DATABASE_CONNECTION") private readonly db: Db, // Inject the MongoDB connection
10+
) {}
11+
12+
async onModuleInit(): Promise<void> {
13+
try {
14+
if (this.hasRun) {
15+
// Check if migration has already run
16+
return;
17+
}
18+
19+
const superadminsCollection = this.db.collection(Collections.SUPERADMINS);
20+
21+
// Check if super admin already exists
22+
const existingSuperAdmin = await superadminsCollection.findOne({
23+
emails: { $in: ["[email protected]"] },
24+
});
25+
26+
if (!existingSuperAdmin) {
27+
const superAdmin = {
28+
emails: ["[email protected]"],
29+
};
30+
31+
await superadminsCollection.insertOne(superAdmin);
32+
console.log("\x1b[36mSuper admin created successfully.\x1b[0m");
33+
} else {
34+
console.log("\x1b[33mSuper admin already exists. Skipping.\x1b[0m");
35+
}
36+
37+
this.hasRun = true; // Set flag after successful execution
38+
} catch (error) {
39+
console.error("Error during super admin migration:", error);
40+
}
41+
}
42+
}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import { Db, MongoClient } from "mongodb";
2+
import { Collections } from "@src/modules/common/enum/database.collection.enum";
3+
4+
/**
5+
* Migration to convert stripePromoCodeId to promoCodeProvider array structure
6+
* This migration updates existing promo codes from the old structure:
7+
* { stripePromoCodeId: "promo_123" }
8+
*
9+
* To the new structure:
10+
* { promoCodeProvider: [{ id: "promo_123", provider: "stripe" }] }
11+
*/
12+
export class MigratePromoCodeProviderMigration {
13+
constructor(private readonly db: Db) {}
14+
15+
async up(): Promise<void> {
16+
console.log("Starting promo code provider migration...");
17+
18+
const collection = this.db.collection(Collections.PROMOCODES);
19+
20+
// Find all documents with the old stripePromoCodeId field
21+
const promoCodes = await collection
22+
.find({ stripePromoCodeId: { $exists: true } })
23+
.toArray();
24+
25+
console.log(`Found ${promoCodes.length} promo codes to migrate`);
26+
27+
if (promoCodes.length === 0) {
28+
console.log("No promo codes found with old structure. Migration complete.");
29+
return;
30+
}
31+
32+
// Process each promo code
33+
for (const promoCode of promoCodes) {
34+
try {
35+
// Create the new promoCodeProvider array
36+
const promoCodeProvider = [
37+
{
38+
id: promoCode.stripePromoCodeId,
39+
provider: "stripe"
40+
}
41+
];
42+
43+
// Update the document
44+
await collection.updateOne(
45+
{ _id: promoCode._id },
46+
{
47+
$set: { promoCodeProvider },
48+
$unset: { stripePromoCodeId: "" }
49+
}
50+
);
51+
52+
console.log(`Migrated promo code: ${promoCode.code} (${promoCode._id})`);
53+
} catch (error) {
54+
console.error(`Failed to migrate promo code ${promoCode.code}:`, error);
55+
throw error;
56+
}
57+
}
58+
59+
console.log(`Successfully migrated ${promoCodes.length} promo codes`);
60+
}
61+
62+
async down(): Promise<void> {
63+
console.log("Rolling back promo code provider migration...");
64+
65+
const collection = this.db.collection(Collections.PROMOCODES);
66+
67+
// Find all documents with the new promoCodeProvider field
68+
const promoCodes = await collection
69+
.find({ promoCodeProvider: { $exists: true } })
70+
.toArray();
71+
72+
console.log(`Found ${promoCodes.length} promo codes to rollback`);
73+
74+
if (promoCodes.length === 0) {
75+
console.log("No promo codes found with new structure. Rollback complete.");
76+
return;
77+
}
78+
79+
// Process each promo code
80+
for (const promoCode of promoCodes) {
81+
try {
82+
// Find the stripe provider entry
83+
const stripeProvider = promoCode.promoCodeProvider?.find(
84+
(provider: any) => provider.provider === "stripe"
85+
);
86+
87+
if (stripeProvider) {
88+
// Restore the old stripePromoCodeId field
89+
await collection.updateOne(
90+
{ _id: promoCode._id },
91+
{
92+
$set: { stripePromoCodeId: stripeProvider.id },
93+
$unset: { promoCodeProvider: "" }
94+
}
95+
);
96+
97+
console.log(`Rolled back promo code: ${promoCode.code} (${promoCode._id})`);
98+
} else {
99+
console.log(`No stripe provider found for promo code: ${promoCode.code}`);
100+
}
101+
} catch (error) {
102+
console.error(`Failed to rollback promo code ${promoCode.code}:`, error);
103+
throw error;
104+
}
105+
}
106+
107+
console.log(`Successfully rolled back ${promoCodes.length} promo codes`);
108+
}
109+
}
110+
111+
// Migration runner function
112+
export async function runPromoCodeProviderMigration(
113+
mongoUrl: string,
114+
dbName: string,
115+
direction: "up" | "down" = "up"
116+
): Promise<void> {
117+
const client = new MongoClient(mongoUrl);
118+
119+
try {
120+
await client.connect();
121+
console.log("Connected to MongoDB");
122+
123+
const db = client.db(dbName);
124+
const migration = new MigratePromoCodeProviderMigration(db);
125+
126+
if (direction === "up") {
127+
await migration.up();
128+
} else {
129+
await migration.down();
130+
}
131+
132+
console.log("Migration completed successfully");
133+
} catch (error) {
134+
console.error("Migration failed:", error);
135+
throw error;
136+
} finally {
137+
await client.close();
138+
console.log("Disconnected from MongoDB");
139+
}
140+
}
141+
142+
// If this file is run directly
143+
if (require.main === module) {
144+
const mongoUrl = process.env.MONGODB_URI || "mongodb://localhost:27017";
145+
const dbName = process.env.DATABASE_NAME || "sparrow";
146+
const direction = (process.argv[2] as "up" | "down") || "up";
147+
148+
runPromoCodeProviderMigration(mongoUrl, dbName, direction)
149+
.then(() => {
150+
console.log("Migration script completed");
151+
process.exit(0);
152+
})
153+
.catch((error) => {
154+
console.error("Migration script failed:", error);
155+
process.exit(1);
156+
});
157+
}

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
"start:create-plan": "ts-node -r tsconfig-paths/register src/create-plan.ts",
3333
"start:upgrade-plan": "ts-node -r tsconfig-paths/register src/upgrade-plan.ts",
3434
"start:migration-mock-url": "ts-node -r tsconfig-paths/register src/migrationMockRequestUrl.ts",
35-
"start:migration-hub-billing": "ts-node -r tsconfig-paths/register src/migrationHubBilling.ts"
35+
"start:migration-hub-billing": "ts-node -r tsconfig-paths/register src/migrationHubBilling.ts",
36+
"start:migration-superadmin": "ts-node -r tsconfig-paths/register src/migration-superadmin.ts",
37+
"start:migration-promocode-provider": "ts-node -r tsconfig-paths/register src/migration-promocode-provider.ts"
3638
},
3739
"dependencies": {
3840
"@anthropic-ai/sdk": "^0.54.0",
@@ -145,6 +147,6 @@
145147
},
146148
"packageManager": "[email protected]",
147149
"optionalDependencies": {
148-
"@sparrowapp-dev/stripe-billing": "^1.2.2"
150+
"@sparrowapp-dev/stripe-billing": "^1.2.7"
149151
}
150152
}

pnpm-lock.yaml

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)