Skip to content

Commit 93cb130

Browse files
committed
feat: backend upgraded.
1 parent b9f9fc6 commit 93cb130

23 files changed

Lines changed: 408 additions & 59 deletions

backend/check-db-state.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import pkg from 'pg';
2+
const { Client } = pkg;
3+
4+
const client = new Client({
5+
host: 'db.xomasbwwhhcxrptfdees.supabase.co',
6+
user: 'postgres',
7+
database: 'postgres',
8+
password: 'pluto1234!@#$%^_',
9+
port: 6543,
10+
ssl: { rejectUnauthorized: false }
11+
});
12+
13+
async function main() {
14+
await client.connect();
15+
16+
// List all tables in public schema
17+
const tables = await client.query(`
18+
SELECT tablename FROM pg_tables WHERE schemaname = 'public' ORDER BY tablename;
19+
`);
20+
console.log('Tables:', tables.rows.map(r => r.tablename));
21+
22+
// Check columns in merchants table if it exists
23+
const merchantTables = tables.rows.filter(r => r.tablename === 'merchants');
24+
if (merchantTables.length > 0) {
25+
const cols = await client.query(`
26+
SELECT column_name FROM information_schema.columns
27+
WHERE table_schema = 'public' AND table_name = 'merchants'
28+
ORDER BY ordinal_position;
29+
`);
30+
console.log('merchants columns:', cols.rows.map(r => r.column_name));
31+
}
32+
33+
// Check migration history
34+
const migTables = tables.rows.filter(r => r.tablename === 'knex_migrations');
35+
if (migTables.length > 0) {
36+
const migs = await client.query('SELECT * FROM knex_migrations ORDER BY id');
37+
console.log('Completed migrations:', migs.rows);
38+
}
39+
40+
await client.end();
41+
}
42+
43+
main().catch(err => console.error(err.message));

backend/check-lock.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import pkg from 'pg';
2+
const { Client } = pkg;
3+
import 'dotenv/config';
4+
5+
async function checkLock() {
6+
const client = new Client({
7+
host: 'db.xomasbwwhhcxrptfdees.supabase.co',
8+
user: 'postgres',
9+
database: 'postgres',
10+
password: 'pluto1234!@#$%^_',
11+
port: 6543,
12+
ssl: { rejectUnauthorized: false }
13+
});
14+
15+
try {
16+
await client.connect();
17+
console.log('Connected to DB.');
18+
19+
const checkTable = await client.query("SELECT to_regclass('knex_migrations_lock')");
20+
if (checkTable.rows[0].to_regclass) {
21+
const res = await client.query('SELECT * FROM knex_migrations_lock');
22+
console.log('Lock table content:', res.rows);
23+
24+
if (res.rows[0] && res.rows[0].is_locked) {
25+
console.log('Database is LOCKED. Clearing lock...');
26+
await client.query('UPDATE knex_migrations_lock SET is_locked = 0');
27+
console.log('Lock cleared.');
28+
} else {
29+
console.log('Database is not locked.');
30+
}
31+
} else {
32+
console.log('knex_migrations_lock table does not exist yet.');
33+
}
34+
35+
await client.end();
36+
} catch (err) {
37+
console.error('Error:', err.message);
38+
}
39+
}
40+
41+
checkLock();

backend/knexfile.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import "dotenv/config";
44
const config = {
55
client: "pg",
66
connection: {
7-
connectionString: process.env.DATABASE_URL,
8-
ssl: process.env.DATABASE_URL?.includes("supabase.co")
9-
? { rejectUnauthorized: false }
10-
: false,
7+
host: 'db.xomasbwwhhcxrptfdees.supabase.co',
8+
user: 'postgres',
9+
database: 'postgres',
10+
password: 'pluto1234!@#$%^_',
11+
port: 6543,
12+
ssl: { rejectUnauthorized: false },
1113
},
1214
migrations: {
1315
directory: "./migrations",

backend/migrations/20260326000002_add_merchant_recipient.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
*/
44

55
export async function up(knex) {
6-
await knex.schema.alterTable("merchants", (t) => {
7-
t.text("recipient");
8-
});
6+
const hasRecipient = await knex.schema.hasColumn("merchants", "recipient");
7+
if (!hasRecipient) {
8+
await knex.schema.alterTable("merchants", (t) => {
9+
t.text("recipient");
10+
});
11+
}
912
await knex.raw(
1013
"create index if not exists merchants_recipient_idx on merchants(recipient)"
1114
);

backend/migrations/20260327000007_add_webhook_version.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
* @returns { Promise<void> }
44
*/
55
export async function up(knex) {
6-
await knex.schema.alterTable("merchants", (table) => {
7-
// Default 'v1' ensures every existing merchant keeps receiving the
8-
// payload format they integrated against without any manual data migration.
9-
table.text("webhook_version").notNullable().defaultTo("v1");
10-
});
6+
const has = await knex.schema.hasColumn("merchants", "webhook_version");
7+
if (!has) {
8+
await knex.schema.alterTable("merchants", (table) => {
9+
table.text("webhook_version").notNullable().defaultTo("v1");
10+
});
11+
}
1112
}
1213

1314
/**
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export async function up(knex) {
2+
await knex.schema.alterTable("merchants", (t) => {
3+
t.text("password_hash").nullable();
4+
});
5+
}
6+
7+
export async function down(knex) {
8+
await knex.schema.alterTable("merchants", (t) => {
9+
t.dropColumn("password_hash");
10+
});
11+
}

backend/package-lock.json

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

backend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"framer-motion": "^12.38.0",
3636
"knex": "^3.2.6",
3737
"morgan": "^1.10.0",
38+
"node-cron": "^4.2.1",
3839
"pg": "^8.20.0",
3940
"pino": "^9.5.0",
4041
"pino-http": "^10.3.0",

backend/reset-db.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import pkg from 'pg';
2+
const { Client } = pkg;
3+
4+
const client = new Client({
5+
host: 'db.xomasbwwhhcxrptfdees.supabase.co',
6+
user: 'postgres',
7+
database: 'postgres',
8+
password: 'pluto1234!@#$%^_',
9+
port: 6543,
10+
ssl: { rejectUnauthorized: false }
11+
});
12+
13+
async function main() {
14+
await client.connect();
15+
console.log('Connected.');
16+
17+
// Drop all application tables to start fresh since migration 001 only partially ran
18+
console.log('Dropping any partial tables...');
19+
const tables = await client.query(`
20+
SELECT tablename FROM pg_tables WHERE schemaname = 'public'
21+
AND tablename NOT LIKE 'knex%'
22+
ORDER BY tablename;
23+
`);
24+
25+
const appTables = tables.rows.map(r => r.tablename);
26+
console.log('Application tables to drop:', appTables);
27+
28+
if (appTables.length > 0) {
29+
// Drop in reverse dependency order
30+
await client.query(`DROP TABLE IF EXISTS ${appTables.map(t => `"${t}"`).join(', ')} CASCADE`);
31+
console.log('Tables dropped.');
32+
} else {
33+
console.log('No application tables found, DB is clean.');
34+
}
35+
36+
// Clear any migration records so knex starts fresh
37+
await client.query('DELETE FROM knex_migrations');
38+
console.log('Migration history cleared.');
39+
40+
await client.end();
41+
console.log('Done. Ready for fresh migration run.');
42+
}
43+
44+
main().catch(err => { console.error(err.message); process.exit(1); });

backend/run-migrations.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Run all knex migrations programmatically using the known-working pg config
2+
import knex from 'knex';
3+
4+
const db = knex({
5+
client: 'pg',
6+
connection: {
7+
host: 'db.xomasbwwhhcxrptfdees.supabase.co',
8+
user: 'postgres',
9+
database: 'postgres',
10+
password: 'pluto1234!@#$%^_',
11+
port: 6543,
12+
ssl: { rejectUnauthorized: false },
13+
},
14+
migrations: {
15+
directory: './migrations',
16+
extension: 'js',
17+
},
18+
});
19+
20+
async function main() {
21+
console.log('Testing connection...');
22+
await db.raw('SELECT 1');
23+
console.log('Connection OK.');
24+
25+
console.log('Running migrations...');
26+
const [batch, list] = await db.migrate.latest();
27+
console.log(`Batch: ${batch}`);
28+
console.log('Applied migrations:', list);
29+
30+
await db.destroy();
31+
console.log('Done!');
32+
}
33+
34+
main().catch(err => {
35+
console.error('Error:', err.message);
36+
process.exit(1);
37+
});

0 commit comments

Comments
 (0)