Fix native install schema gaps (closes #20)
Mirror to GitHub / mirror (push) Successful in 1m38s
Test and Lint / backend-test (push) Successful in 1m44s
Test and Lint / frontend-test (push) Successful in 2m12s
Version and Release / version-bump (push) Failing after 1m20s
Version and Release / trigger-drone (push) Has been skipped
Mirror to GitHub / mirror (push) Successful in 1m38s
Test and Lint / backend-test (push) Successful in 1m44s
Test and Lint / frontend-test (push) Successful in 2m12s
Version and Release / version-bump (push) Failing after 1m20s
Version and Release / trigger-drone (push) Has been skipped
This commit is contained in:
@@ -209,6 +209,7 @@ These features are currently in beta testing and may have limited functionality
|
|||||||
| **Gallery Feedback** | Allow guests to like, rate, and comment on photos with admin notifications and moderation | Medium | ✅ Implemented |
|
| **Gallery Feedback** | Allow guests to like, rate, and comment on photos with admin notifications and moderation | Medium | ✅ Implemented |
|
||||||
| **Video Support** | Upload and display videos alongside photos in galleries with streaming support | Low | 🔄 Open |
|
| **Video Support** | Upload and display videos alongside photos in galleries with streaming support | Low | 🔄 Open |
|
||||||
| **Multiple Administrators** | Support for multiple admin accounts with role-based permissions and activity tracking | Low | 📋 Planned |
|
| **Multiple Administrators** | Support for multiple admin accounts with role-based permissions and activity tracking | Low | 📋 Planned |
|
||||||
|
| **Filtering & Export Options** | Add filters to show only rated, liked, or marked photos and export filtered selections for Capture One or Lightroom workflows | Low | 🔄 Open |
|
||||||
|
|
||||||
**Status Legend:** ✅ Implemented | 🚧 In Progress | 🔄 Open | 📋 Planned
|
**Status Legend:** ✅ Implemented | 🚧 In Progress | 🔄 Open | 📋 Planned
|
||||||
|
|
||||||
|
|||||||
@@ -292,6 +292,7 @@ sudo systemctl stop picpeak-backend picpeak-workers
|
|||||||
sudo systemctl restart picpeak-backend picpeak-workers
|
sudo systemctl restart picpeak-backend picpeak-workers
|
||||||
|
|
||||||
# Update PicPeak
|
# Update PicPeak
|
||||||
|
# (reruns migrations to pick up schema fixes for native installs)
|
||||||
sudo ./setup.sh --update
|
sudo ./setup.sh --update
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
const logger = require('../../src/utils/logger');
|
||||||
|
|
||||||
|
async function ensureColumn(knex, tableName, columnName, alterFn) {
|
||||||
|
const exists = await knex.schema.hasColumn(tableName, columnName);
|
||||||
|
if (!exists) {
|
||||||
|
logger.info(`Adding column ${tableName}.${columnName}`);
|
||||||
|
await knex.schema.table(tableName, alterFn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.up = async function(knex) {
|
||||||
|
await ensureColumn(knex, 'events', 'host_name', (table) => {
|
||||||
|
table.string('host_name');
|
||||||
|
});
|
||||||
|
|
||||||
|
await ensureColumn(knex, 'events', 'allow_user_uploads', (table) => {
|
||||||
|
table.boolean('allow_user_uploads').defaultTo(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
await ensureColumn(knex, 'events', 'upload_category_id', (table) => {
|
||||||
|
table.integer('upload_category_id');
|
||||||
|
});
|
||||||
|
|
||||||
|
await ensureColumn(knex, 'events', 'allow_downloads', (table) => {
|
||||||
|
table.boolean('allow_downloads').defaultTo(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
await ensureColumn(knex, 'events', 'disable_right_click', (table) => {
|
||||||
|
table.boolean('disable_right_click').defaultTo(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
await ensureColumn(knex, 'events', 'watermark_downloads', (table) => {
|
||||||
|
table.boolean('watermark_downloads').defaultTo(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
await ensureColumn(knex, 'events', 'watermark_text', (table) => {
|
||||||
|
table.text('watermark_text');
|
||||||
|
});
|
||||||
|
|
||||||
|
await ensureColumn(knex, 'events', 'hero_photo_id', (table) => {
|
||||||
|
table.integer('hero_photo_id').references('id').inTable('photos').onDelete('SET NULL');
|
||||||
|
});
|
||||||
|
|
||||||
|
await ensureColumn(knex, 'photos', 'uploaded_by', (table) => {
|
||||||
|
table.string('uploaded_by').defaultTo('admin');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.down = async function() {
|
||||||
|
// Non destructive migration; no rollback
|
||||||
|
};
|
||||||
@@ -75,6 +75,13 @@ async function initializeDatabase() {
|
|||||||
table.boolean('is_archived').defaultTo(false);
|
table.boolean('is_archived').defaultTo(false);
|
||||||
table.string('archive_path');
|
table.string('archive_path');
|
||||||
table.datetime('archived_at');
|
table.datetime('archived_at');
|
||||||
|
table.boolean('allow_user_uploads').defaultTo(false);
|
||||||
|
table.integer('upload_category_id');
|
||||||
|
table.boolean('allow_downloads').defaultTo(true);
|
||||||
|
table.boolean('disable_right_click').defaultTo(false);
|
||||||
|
table.boolean('watermark_downloads').defaultTo(false);
|
||||||
|
table.text('watermark_text');
|
||||||
|
table.integer('hero_photo_id').references('id').inTable('photos').onDelete('SET NULL');
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Check if color_theme needs to be updated to TEXT type
|
// Check if color_theme needs to be updated to TEXT type
|
||||||
@@ -104,11 +111,39 @@ async function initializeDatabase() {
|
|||||||
archive_path TEXT,
|
archive_path TEXT,
|
||||||
archived_at DATETIME,
|
archived_at DATETIME,
|
||||||
allow_user_uploads BOOLEAN DEFAULT 0,
|
allow_user_uploads BOOLEAN DEFAULT 0,
|
||||||
upload_category_id INTEGER
|
upload_category_id INTEGER,
|
||||||
|
allow_downloads BOOLEAN DEFAULT 1,
|
||||||
|
disable_right_click BOOLEAN DEFAULT 0,
|
||||||
|
watermark_downloads BOOLEAN DEFAULT 0,
|
||||||
|
watermark_text TEXT,
|
||||||
|
hero_photo_id INTEGER
|
||||||
)
|
)
|
||||||
`);
|
`);
|
||||||
|
|
||||||
await db.raw('INSERT INTO events_new SELECT * FROM events');
|
const pragmaRows = await db.raw("PRAGMA table_info('events')");
|
||||||
|
const existingColumns = pragmaRows.map(row => row.name);
|
||||||
|
const selectColumns = existingColumns.map((col) => {
|
||||||
|
switch (col) {
|
||||||
|
case 'allow_user_uploads':
|
||||||
|
return "COALESCE(allow_user_uploads, 0) as allow_user_uploads";
|
||||||
|
case 'upload_category_id':
|
||||||
|
return "upload_category_id";
|
||||||
|
case 'allow_downloads':
|
||||||
|
return "COALESCE(allow_downloads, 1) as allow_downloads";
|
||||||
|
case 'disable_right_click':
|
||||||
|
return "COALESCE(disable_right_click, 0) as disable_right_click";
|
||||||
|
case 'watermark_downloads':
|
||||||
|
return "COALESCE(watermark_downloads, 0) as watermark_downloads";
|
||||||
|
case 'watermark_text':
|
||||||
|
return 'watermark_text';
|
||||||
|
case 'hero_photo_id':
|
||||||
|
return 'hero_photo_id';
|
||||||
|
default:
|
||||||
|
return col;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.raw(`INSERT INTO events_new (${existingColumns.join(', ')}) SELECT ${selectColumns.join(', ')} FROM events`);
|
||||||
await db.raw('DROP TABLE events');
|
await db.raw('DROP TABLE events');
|
||||||
await db.raw('ALTER TABLE events_new RENAME TO events');
|
await db.raw('ALTER TABLE events_new RENAME TO events');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -129,6 +164,7 @@ async function initializeDatabase() {
|
|||||||
table.string('thumbnail_path');
|
table.string('thumbnail_path');
|
||||||
table.string('type').notNullable(); // 'collage' or 'individual'
|
table.string('type').notNullable(); // 'collage' or 'individual'
|
||||||
table.integer('size_bytes');
|
table.integer('size_bytes');
|
||||||
|
table.string('uploaded_by').defaultTo('admin');
|
||||||
table.datetime('uploaded_at').defaultTo(db.fn.now());
|
table.datetime('uploaded_at').defaultTo(db.fn.now());
|
||||||
table.integer('view_count').defaultTo(0);
|
table.integer('view_count').defaultTo(0);
|
||||||
table.integer('download_count').defaultTo(0);
|
table.integer('download_count').defaultTo(0);
|
||||||
|
|||||||
Reference in New Issue
Block a user