Compare commits

...

7 Commits

Author SHA1 Message Date
Gitea Actions Bot c95784eda9 chore: bump backend version to 1.0.81
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is failing
2025-07-23 06:35:20 +00:00
paul f49dbed2d8 fix: remove updated_at from app_settings inserts in multiple migrations
Mirror to GitHub / mirror (push) Successful in 32s
Test and Lint / backend-test (push) Successful in 1m25s
continuous-integration/drone/push Build is passing
Test and Lint / frontend-test (push) Successful in 2m2s
Version and Release / version-bump (push) Successful in 36s
Version and Release / trigger-drone (push) Successful in 3s
The app_settings table in production doesn't have created_at/updated_at columns.
Fixed inconsistent usage across migrations:
- Migration 014: removed updated_at: new Date()
- Migration 027: removed updated_at: knex.fn.now()
- Migration 033: removed updated_at: new Date()

This ensures all migrations are consistent and won't fail in production.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-23 08:30:19 +02:00
paul 1480fa31c7 CRITICAL FIX: remove created_at/updated_at from migration 032 inserts
Mirror to GitHub / mirror (push) Successful in 31s
Test and Lint / backend-test (push) Successful in 1m16s
Version and Release / version-bump (push) Has been cancelled
Test and Lint / frontend-test (push) Has been cancelled
Version and Release / trigger-drone (push) Has been cancelled
continuous-integration/drone/push Build is passing
Production was failing because app_settings and email_templates
tables don't have created_at/updated_at columns. Removed these
fields from all insert statements to restore service.

This is a critical production fix - system was down.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-23 08:28:03 +02:00
Gitea Actions Bot 769dff4364 chore: bump backend version to 1.0.80
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is failing
2025-07-23 05:30:06 +00:00
paul d2e0e75e9a fix: force github-release plugin to use GitHub API instead of Gitea
Mirror to GitHub / mirror (push) Successful in 35s
Test and Lint / backend-test (push) Successful in 1m29s
continuous-integration/drone/push Build is passing
Test and Lint / frontend-test (push) Successful in 2m3s
The plugin was auto-detecting the Gitea instance and using its API
instead of GitHub's. Fixed by:
- Adding explicit environment variables to override detection
- Removing deprecated github_url/github_upload_url parameters
- Setting DRONE_REMOTE_URL to point to GitHub

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-23 07:29:14 +02:00
paul 041f3b58f4 fix: remove unused formatBoolean import from migration 033
Mirror to GitHub / mirror (push) Successful in 33s
Test and Lint / backend-test (push) Successful in 1m24s
Test and Lint / frontend-test (push) Has been cancelled
Version and Release / version-bump (push) Successful in 42s
continuous-integration/drone/push Build is passing
Version and Release / trigger-drone (push) Successful in 3s
Removed unnecessary import that could cause issues if helpers.js
doesn't define formatBoolean. Migration already uses correct
boolean syntax without the helper.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-23 07:26:30 +02:00
paul 0f4db08883 fix: remove formatBoolean calls from migration 032 - critical production fix
Mirror to GitHub / mirror (push) Successful in 30s
Test and Lint / frontend-test (push) Has been cancelled
Test and Lint / backend-test (push) Has been cancelled
Version and Release / version-bump (push) Has been cancelled
Version and Release / trigger-drone (push) Has been cancelled
continuous-integration/drone/push Build is passing
Migration was failing with "formatBoolean is not a function" error,
preventing backend startup. Fixed by:
- Removing formatBoolean import
- Using direct boolean values for column defaults
- Using JSON.stringify for setting values

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-23 07:25:10 +02:00
7 changed files with 33 additions and 51 deletions
+6
View File
@@ -111,11 +111,17 @@ steps:
# -------- NEW: Create GitHub Release -------- # -------- NEW: Create GitHub Release --------
- name: github-release - name: github-release
image: plugins/github-release image: plugins/github-release
environment:
PLUGIN_API_KEY:
from_secret: GITHUB_TOKEN
DRONE_REMOTE_URL: https://github.com/the-luap/picpeak.git
settings: settings:
api_key: api_key:
from_secret: GITHUB_TOKEN from_secret: GITHUB_TOKEN
repo: the-luap/picpeak repo: the-luap/picpeak
title: "PicPeak ${DRONE_TAG}" title: "PicPeak ${DRONE_TAG}"
prerelease: false
overwrite: true
note: | note: |
# PicPeak ${DRONE_TAG} # PicPeak ${DRONE_TAG}
@@ -8,8 +8,7 @@ exports.up = async function(knex) {
await knex('app_settings').insert({ await knex('app_settings').insert({
setting_key: 'general_default_welcome_message', setting_key: 'general_default_welcome_message',
setting_value: JSON.stringify('Thank you for using our photo sharing service! We hope you enjoy your photos.'), setting_value: JSON.stringify('Thank you for using our photo sharing service! We hope you enjoy your photos.'),
setting_type: 'general', setting_type: 'general'
updated_at: new Date()
}); });
} }
@@ -41,8 +41,7 @@ exports.up = async function(knex) {
if (!exists) { if (!exists) {
await knex('app_settings').insert({ await knex('app_settings').insert({
...setting, ...setting
updated_at: knex.fn.now()
}); });
} }
} }
@@ -1,4 +1,4 @@
const { formatBoolean, parseBoolean } = require('./helpers'); // No helpers needed for this migration
/** /**
* Add restore_runs table for tracking restore operations * Add restore_runs table for tracking restore operations
@@ -30,9 +30,9 @@ exports.up = async function(knex) {
table.string('pre_restore_backup_path', 500); // Path to pre-restore safety backup table.string('pre_restore_backup_path', 500); // Path to pre-restore safety backup
// Flags // Flags
table.boolean('is_dry_run').defaultTo(formatBoolean(false)); table.boolean('is_dry_run').defaultTo(false);
table.boolean('was_rollback_attempted').defaultTo(formatBoolean(false)); table.boolean('was_rollback_attempted').defaultTo(false);
table.boolean('was_successful').defaultTo(formatBoolean(false)); table.boolean('was_successful').defaultTo(false);
// Operator information // Operator information
table.string('operator_type', 50).defaultTo('manual'); // manual, scheduled, api table.string('operator_type', 50).defaultTo('manual'); // manual, scheduled, api
@@ -59,7 +59,7 @@ exports.up = async function(knex) {
table.bigInteger('file_size'); table.bigInteger('file_size');
table.string('checksum', 64); table.string('checksum', 64);
table.boolean('checksum_verified').defaultTo(formatBoolean(false)); table.boolean('checksum_verified').defaultTo(false);
table.text('error_message'); table.text('error_message');
table.timestamp('started_at'); table.timestamp('started_at');
@@ -92,51 +92,39 @@ exports.up = async function(knex) {
await knex('app_settings').insert([ await knex('app_settings').insert([
{ {
setting_key: 'restore_allow_force', setting_key: 'restore_allow_force',
setting_value: formatBoolean(false), setting_value: JSON.stringify(false),
setting_type: 'restore', setting_type: 'restore',
description: 'Allow force restore with warnings', description: 'Allow force restore with warnings'
created_at: knex.fn.now(),
updated_at: knex.fn.now()
}, },
{ {
setting_key: 'restore_require_pre_backup', setting_key: 'restore_require_pre_backup',
setting_value: formatBoolean(true), setting_value: JSON.stringify(true),
setting_type: 'restore', setting_type: 'restore',
description: 'Require pre-restore backup', description: 'Require pre-restore backup'
created_at: knex.fn.now(),
updated_at: knex.fn.now()
}, },
{ {
setting_key: 'restore_max_file_size_mb', setting_key: 'restore_max_file_size_mb',
setting_value: '5000', setting_value: '5000',
setting_type: 'restore', setting_type: 'restore',
description: 'Maximum file size for restore (MB)', description: 'Maximum file size for restore (MB)'
created_at: knex.fn.now(),
updated_at: knex.fn.now()
}, },
{ {
setting_key: 'restore_verify_checksums', setting_key: 'restore_verify_checksums',
setting_value: formatBoolean(true), setting_value: JSON.stringify(true),
setting_type: 'restore', setting_type: 'restore',
description: 'Verify file checksums during restore', description: 'Verify file checksums during restore'
created_at: knex.fn.now(),
updated_at: knex.fn.now()
}, },
{ {
setting_key: 'restore_email_on_completion', setting_key: 'restore_email_on_completion',
setting_value: formatBoolean(true), setting_value: JSON.stringify(true),
setting_type: 'restore', setting_type: 'restore',
description: 'Send email on restore completion', description: 'Send email on restore completion'
created_at: knex.fn.now(),
updated_at: knex.fn.now()
}, },
{ {
setting_key: 'restore_retention_days', setting_key: 'restore_retention_days',
setting_value: '30', setting_value: '30',
setting_type: 'restore', setting_type: 'restore',
description: 'Days to retain restore history', description: 'Days to retain restore history'
created_at: knex.fn.now(),
updated_at: knex.fn.now()
} }
]); ]);
@@ -159,9 +147,7 @@ exports.up = async function(knex) {
<p>Please verify that all systems are functioning correctly after the restore.</p>`, <p>Please verify that all systems are functioning correctly after the restore.</p>`,
language: 'en', language: 'en',
is_active: formatBoolean(true), is_active: true
created_at: knex.fn.now(),
updated_at: knex.fn.now()
}, },
{ {
name: 'restore_failed', name: 'restore_failed',
@@ -180,9 +166,7 @@ exports.up = async function(knex) {
<p><strong>Important:</strong> If a pre-restore backup was created, it may be used for recovery.</p>`, <p><strong>Important:</strong> If a pre-restore backup was created, it may be used for recovery.</p>`,
language: 'en', language: 'en',
is_active: formatBoolean(true), is_active: true
created_at: knex.fn.now(),
updated_at: knex.fn.now()
}, },
{ {
name: 'restore_completed', name: 'restore_completed',
@@ -201,9 +185,7 @@ exports.up = async function(knex) {
<p>Bitte überprüfen Sie, ob alle Systeme nach der Wiederherstellung ordnungsgemäß funktionieren.</p>`, <p>Bitte überprüfen Sie, ob alle Systeme nach der Wiederherstellung ordnungsgemäß funktionieren.</p>`,
language: 'de', language: 'de',
is_active: formatBoolean(true), is_active: true
created_at: knex.fn.now(),
updated_at: knex.fn.now()
}, },
{ {
name: 'restore_failed', name: 'restore_failed',
@@ -222,9 +204,7 @@ exports.up = async function(knex) {
<p><strong>Wichtig:</strong> Falls ein Backup vor der Wiederherstellung erstellt wurde, kann es zur Wiederherstellung verwendet werden.</p>`, <p><strong>Wichtig:</strong> Falls ein Backup vor der Wiederherstellung erstellt wurde, kann es zur Wiederherstellung verwendet werden.</p>`,
language: 'de', language: 'de',
is_active: formatBoolean(true), is_active: true
created_at: knex.fn.now(),
updated_at: knex.fn.now()
} }
]; ];
@@ -1,4 +1,4 @@
const { formatBoolean } = require('./helpers'); // No helpers needed for boolean values
exports.up = async function(knex) { exports.up = async function(knex) {
console.log('Adding gallery feedback tables...'); console.log('Adding gallery feedback tables...');
@@ -87,8 +87,7 @@ exports.up = async function(knex) {
{ {
setting_key: 'feedback_notification_email', setting_key: 'feedback_notification_email',
setting_value: JSON.stringify(''), setting_value: JSON.stringify(''),
setting_type: 'feedback', setting_type: 'feedback'
updated_at: new Date()
}, },
{ {
setting_key: 'feedback_rate_limits', setting_key: 'feedback_rate_limits',
@@ -97,8 +96,7 @@ exports.up = async function(knex) {
comment: { max: 20, window: 3600 }, // 20 comments per hour comment: { max: 20, window: 3600 }, // 20 comments per hour
like: { max: 200, window: 3600 } // 200 likes per hour like: { max: 200, window: 3600 } // 200 likes per hour
}), }),
setting_type: 'feedback', setting_type: 'feedback'
updated_at: new Date()
} }
]); ]);
+2 -2
View File
@@ -1,12 +1,12 @@
{ {
"name": "picpeak-backend", "name": "picpeak-backend",
"version": "1.0.79", "version": "1.0.81",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "picpeak-backend", "name": "picpeak-backend",
"version": "1.0.79", "version": "1.0.81",
"dependencies": { "dependencies": {
"@aws-sdk/client-s3": "^3.850.0", "@aws-sdk/client-s3": "^3.850.0",
"@aws-sdk/lib-storage": "^3.850.0", "@aws-sdk/lib-storage": "^3.850.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "picpeak-backend", "name": "picpeak-backend",
"version": "1.0.79", "version": "1.0.81",
"description": "Backend for PicPeak event photo sharing platform", "description": "Backend for PicPeak event photo sharing platform",
"main": "server.js", "main": "server.js",
"scripts": { "scripts": {