Merge release/v0.2.1: Critical database persistence fix
This commit is contained in:
@@ -4,6 +4,22 @@ set -e # Exit on any error
|
||||
# Ensure data directory exists
|
||||
mkdir -p /app/data
|
||||
|
||||
echo "=== Sneaky Klaus Container Startup ==="
|
||||
echo "Data directory: /app/data"
|
||||
echo "Database path: /app/data/sneaky-klaus.db"
|
||||
|
||||
# Check if database exists
|
||||
if [ -f /app/data/sneaky-klaus.db ]; then
|
||||
echo "Existing database found ($(ls -lh /app/data/sneaky-klaus.db | awk '{print $5}'))"
|
||||
else
|
||||
echo "No existing database - will be created by migrations"
|
||||
fi
|
||||
|
||||
# List contents of data directory
|
||||
echo "Data directory contents:"
|
||||
ls -la /app/data/ || echo "(empty)"
|
||||
|
||||
echo ""
|
||||
echo "Running database migrations..."
|
||||
if uv run alembic upgrade head; then
|
||||
echo "Database migrations completed successfully"
|
||||
@@ -13,5 +29,6 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Starting application server..."
|
||||
exec gunicorn --bind 0.0.0.0:8000 --workers 2 --threads 4 main:app
|
||||
|
||||
@@ -24,7 +24,8 @@ if config.config_file_name is not None:
|
||||
# Create minimal Flask app for migrations (without session initialization)
|
||||
# This avoids Flask-Session trying to create tables before migrations run
|
||||
app = Flask(__name__)
|
||||
BASE_DIR = Path(__file__).parent.parent
|
||||
# Use resolve() to ensure absolute paths - critical for database persistence
|
||||
BASE_DIR = Path(__file__).parent.parent.resolve()
|
||||
DATA_DIR = BASE_DIR / "data"
|
||||
DATA_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ from pathlib import Path
|
||||
class Config:
|
||||
"""Base configuration class with common settings."""
|
||||
|
||||
# Base paths
|
||||
BASE_DIR = Path(__file__).parent.parent
|
||||
# Base paths - use resolve() to ensure absolute paths
|
||||
BASE_DIR = Path(__file__).parent.parent.resolve()
|
||||
DATA_DIR = BASE_DIR / "data"
|
||||
|
||||
# Security
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
<tr>
|
||||
<td>{{ exchange.name }}</td>
|
||||
<td><mark>{{ exchange.state }}</mark></td>
|
||||
<td>0 / {{ exchange.max_participants }}</td>
|
||||
<td>{{ exchange.participants|selectattr('withdrawn_at', 'none')|list|length }} / {{ exchange.max_participants }}</td>
|
||||
<td>{{ exchange.exchange_date.strftime('%Y-%m-%d') }}</td>
|
||||
<td>
|
||||
<a href="{{ url_for('admin.view_exchange', exchange_id=exchange.id) }}">View</a>
|
||||
|
||||
@@ -37,8 +37,30 @@
|
||||
</div>
|
||||
|
||||
<div class="detail-section">
|
||||
<h2>Participants</h2>
|
||||
<h2>Participants ({{ exchange.participants|selectattr('withdrawn_at', 'none')|list|length }} / {{ exchange.max_participants }})</h2>
|
||||
{% set active_participants = exchange.participants|selectattr('withdrawn_at', 'none')|list %}
|
||||
{% if active_participants %}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Registered</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for participant in active_participants|sort(attribute='name') %}
|
||||
<tr>
|
||||
<td>{{ participant.name }}</td>
|
||||
<td>{{ participant.email }}</td>
|
||||
<td>{{ participant.created_at.strftime('%Y-%m-%d %H:%M') }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p>No participants yet.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
|
||||
Reference in New Issue
Block a user