Compare commits
No commits in common. "641544f7176bf24ba0436e872c6f3a4cdb6ede84" and "63ab72161d6781883b3f1f087f09cbb970b106d1" have entirely different histories.
641544f717
...
63ab72161d
@ -49,9 +49,6 @@ coverage
|
|||||||
ehthumbs.db
|
ehthumbs.db
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|
||||||
# Explicitly include start.sh
|
|
||||||
!start.sh
|
|
||||||
|
|
||||||
# Git
|
# Git
|
||||||
.git
|
.git
|
||||||
.gitignore
|
.gitignore
|
||||||
|
|||||||
30
.env.dokploy
Normal file
30
.env.dokploy
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# Dokploy Environment Variables
|
||||||
|
# Use these values in your Dokploy environment variables section
|
||||||
|
|
||||||
|
NODE_ENV=production
|
||||||
|
APP_PORT=5173
|
||||||
|
|
||||||
|
# Database (uses Docker volume)
|
||||||
|
DATABASE_URL=file:/app/data/production.db
|
||||||
|
|
||||||
|
# Security - CHANGE THESE VALUES!
|
||||||
|
SESSION_SECRET=your-super-secure-session-secret-change-this-in-production-min-32-chars
|
||||||
|
ENCRYPTION_KEY=production-secure-encryption-key!
|
||||||
|
SUPER_ADMIN=superadmin
|
||||||
|
SUPER_ADMIN_EMAIL=admin@yourcompany.com
|
||||||
|
SUPER_ADMIN_PASSWORD=YourSecurePassword123!
|
||||||
|
|
||||||
|
# Domain (set to your actual domain)
|
||||||
|
DOMAIN=your-domain.com
|
||||||
|
|
||||||
|
# Mail Settings (optional - for password reset features)
|
||||||
|
MAIL_HOST=
|
||||||
|
MAIL_PORT=587
|
||||||
|
MAIL_SECURE=false
|
||||||
|
MAIL_USERNAME=
|
||||||
|
MAIL_PASSWORD=
|
||||||
|
MAIL_FROM_NAME=Phosphat Report System
|
||||||
|
MAIL_FROM_EMAIL=
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
LOG_LEVEL=info
|
||||||
39
.env.production
Normal file
39
.env.production
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# Production Environment Variables
|
||||||
|
# Copy this file and rename to .env for production deployment
|
||||||
|
# Make sure to change all default values for security
|
||||||
|
|
||||||
|
# Application Settings
|
||||||
|
NODE_ENV=production
|
||||||
|
APP_PORT=5173
|
||||||
|
DOMAIN=your-domain.com
|
||||||
|
|
||||||
|
# Database
|
||||||
|
DATABASE_URL="file:/app/data/production.db"
|
||||||
|
|
||||||
|
# Security
|
||||||
|
SESSION_SECRET="your-super-secure-session-secret-change-this-in-production-min-32-chars"
|
||||||
|
ENCRYPTION_KEY="production-secure-encryption-key!"
|
||||||
|
|
||||||
|
# Super Admin Account (created on first run)
|
||||||
|
SUPER_ADMIN="superadmin"
|
||||||
|
SUPER_ADMIN_EMAIL="admin@yourcompany.com"
|
||||||
|
SUPER_ADMIN_PASSWORD="YourSecurePassword123!"
|
||||||
|
|
||||||
|
# Storage Paths (for bind mounts)
|
||||||
|
DATA_PATH=./data
|
||||||
|
BACKUP_PATH=./backups
|
||||||
|
|
||||||
|
# Backup Schedule (cron format)
|
||||||
|
BACKUP_SCHEDULE="0 2 * * *"
|
||||||
|
|
||||||
|
# Mail Settings (optional - for password reset features)
|
||||||
|
MAIL_HOST=""
|
||||||
|
MAIL_PORT="587"
|
||||||
|
MAIL_SECURE="false"
|
||||||
|
MAIL_USERNAME=""
|
||||||
|
MAIL_PASSWORD=""
|
||||||
|
MAIL_FROM_NAME="Phosphat Report System"
|
||||||
|
MAIL_FROM_EMAIL=""
|
||||||
|
|
||||||
|
# Logging (optional)
|
||||||
|
LOG_LEVEL="info"
|
||||||
@ -1,147 +0,0 @@
|
|||||||
# Deployment Guide for Phosphat Report App
|
|
||||||
|
|
||||||
This guide will help you deploy the Phosphat Report application on your VPS using the provided `compose.yml` file.
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
- Docker and Docker Compose installed on your VPS
|
|
||||||
- Git (to clone the repository)
|
|
||||||
- At least 1GB RAM and 10GB disk space
|
|
||||||
|
|
||||||
## Quick Deployment
|
|
||||||
|
|
||||||
1. **Clone the repository** to your VPS:
|
|
||||||
```bash
|
|
||||||
git clone <your-repo-url>
|
|
||||||
cd phosphat-report-app
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Deploy the application**:
|
|
||||||
```bash
|
|
||||||
docker-compose -f compose.yml up -d --build
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Check the status**:
|
|
||||||
```bash
|
|
||||||
docker-compose -f compose.yml ps
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Access your application**:
|
|
||||||
- URL: `http://your-vps-ip:3000`
|
|
||||||
- Default login: `superadmin` / `P@ssw0rd123!`
|
|
||||||
|
|
||||||
## Environment Variables (Hardcoded in compose.yml)
|
|
||||||
|
|
||||||
The following environment variables are already configured in the `compose.yml` file:
|
|
||||||
|
|
||||||
- **NODE_ENV**: `production`
|
|
||||||
- **DATABASE_URL**: `file:/app/data/production.db`
|
|
||||||
- **SESSION_SECRET**: `your-super-secure-session-secret-change-this-min-32-chars`
|
|
||||||
- **SUPER_ADMIN**: `superadmin`
|
|
||||||
- **SUPER_ADMIN_EMAIL**: `admin@yourcompany.com`
|
|
||||||
- **SUPER_ADMIN_PASSWORD**: `P@ssw0rd123!`
|
|
||||||
- **MAIL_HOST**: `smtp.gmail.com`
|
|
||||||
- **MAIL_PORT**: `587`
|
|
||||||
- **MAIL_USERNAME**: `your-email@gmail.com`
|
|
||||||
- **MAIL_PASSWORD**: `your-app-password`
|
|
||||||
|
|
||||||
## Services Included
|
|
||||||
|
|
||||||
### Main Application (`app`)
|
|
||||||
- **Port**: 3000
|
|
||||||
- **Database**: SQLite with persistent storage
|
|
||||||
- **Health Check**: Available at `/health` endpoint
|
|
||||||
- **Resource Limits**: 512MB RAM, 0.5 CPU
|
|
||||||
|
|
||||||
### Backup Service (`backup`)
|
|
||||||
- **Purpose**: Automatic daily database backups at 2 AM
|
|
||||||
- **Retention**: Keeps backups for 7 days
|
|
||||||
- **Location**: `/backup` volume
|
|
||||||
|
|
||||||
## Useful Commands
|
|
||||||
|
|
||||||
### View logs:
|
|
||||||
```bash
|
|
||||||
docker-compose -f compose.yml logs -f app
|
|
||||||
```
|
|
||||||
|
|
||||||
### Stop services:
|
|
||||||
```bash
|
|
||||||
docker-compose -f compose.yml down
|
|
||||||
```
|
|
||||||
|
|
||||||
### Restart services:
|
|
||||||
```bash
|
|
||||||
docker-compose -f compose.yml restart
|
|
||||||
```
|
|
||||||
|
|
||||||
### Manual backup:
|
|
||||||
```bash
|
|
||||||
docker-compose -f compose.yml exec app cp /app/data/production.db /app/data/backup_$(date +%Y%m%d_%H%M%S).db
|
|
||||||
```
|
|
||||||
|
|
||||||
### Check health:
|
|
||||||
```bash
|
|
||||||
curl http://localhost:3000/health
|
|
||||||
```
|
|
||||||
|
|
||||||
## Volumes
|
|
||||||
|
|
||||||
- **app_data**: Stores the SQLite database
|
|
||||||
- **app_logs**: Application logs
|
|
||||||
- **backup_data**: Database backups
|
|
||||||
|
|
||||||
## Security Notes
|
|
||||||
|
|
||||||
1. **Change default passwords** after first login
|
|
||||||
2. **Update email settings** in the application
|
|
||||||
3. **Configure firewall** to only allow necessary ports
|
|
||||||
4. **Use HTTPS** with a reverse proxy (nginx/traefik) for production
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Application won't start:
|
|
||||||
```bash
|
|
||||||
# Check logs
|
|
||||||
docker-compose -f compose.yml logs app
|
|
||||||
|
|
||||||
# Rebuild without cache
|
|
||||||
docker-compose -f compose.yml build --no-cache app
|
|
||||||
```
|
|
||||||
|
|
||||||
### Database issues:
|
|
||||||
```bash
|
|
||||||
# Reset database (WARNING: This will delete all data)
|
|
||||||
docker-compose -f compose.yml down
|
|
||||||
docker volume rm $(docker volume ls -q | grep app_data)
|
|
||||||
docker-compose -f compose.yml up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
### Port conflicts:
|
|
||||||
If port 3000 is already in use, edit the `compose.yml` file and change:
|
|
||||||
```yaml
|
|
||||||
ports:
|
|
||||||
- "3001:3000" # Change 3000 to any available port
|
|
||||||
```
|
|
||||||
|
|
||||||
## Updating the Application
|
|
||||||
|
|
||||||
1. **Pull latest changes**:
|
|
||||||
```bash
|
|
||||||
git pull origin main
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Rebuild and restart**:
|
|
||||||
```bash
|
|
||||||
docker-compose -f compose.yml up -d --build
|
|
||||||
```
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
For issues and support:
|
|
||||||
1. Check the application logs
|
|
||||||
2. Verify all services are running
|
|
||||||
3. Test the health endpoint
|
|
||||||
4. Check database connectivity
|
|
||||||
|
|
||||||
The application should be accessible at `http://your-vps-ip:3000` after successful deployment.
|
|
||||||
35
Dockerfile
35
Dockerfile
@ -54,6 +54,39 @@ COPY --from=deps --chown=remix:nodejs /app/node_modules ./node_modules
|
|||||||
RUN mkdir -p /app/data /app/logs && \
|
RUN mkdir -p /app/data /app/logs && \
|
||||||
chown -R remix:nodejs /app/data /app/logs
|
chown -R remix:nodejs /app/data /app/logs
|
||||||
|
|
||||||
|
# Create startup script
|
||||||
|
COPY --chown=remix:nodejs <<EOF /app/start.sh
|
||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "Starting Phosphat Report Application..."
|
||||||
|
|
||||||
|
# Run database migrations
|
||||||
|
echo "Running database migrations..."
|
||||||
|
npx prisma db push --accept-data-loss
|
||||||
|
|
||||||
|
# Run seed using production script
|
||||||
|
echo "Seeding database..."
|
||||||
|
if [ -f "scripts/seed-production.js" ]; then
|
||||||
|
echo "Using production seed script..."
|
||||||
|
node scripts/seed-production.js
|
||||||
|
else
|
||||||
|
echo "Production seed script not found, trying alternative methods..."
|
||||||
|
if [ -f "prisma/seed.js" ]; then
|
||||||
|
echo "Using JavaScript seed file..."
|
||||||
|
node prisma/seed.js
|
||||||
|
else
|
||||||
|
echo "No seeding method available, skipping..."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Database setup complete. Starting application on port 3000..."
|
||||||
|
export PORT=3000
|
||||||
|
exec npx remix-serve ./build/server/index.js
|
||||||
|
EOF
|
||||||
|
|
||||||
|
RUN chmod +x /app/start.sh
|
||||||
|
|
||||||
USER remix
|
USER remix
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
@ -67,4 +100,4 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
|||||||
|
|
||||||
# Use dumb-init to handle signals properly
|
# Use dumb-init to handle signals properly
|
||||||
ENTRYPOINT ["dumb-init", "--"]
|
ENTRYPOINT ["dumb-init", "--"]
|
||||||
CMD ["sh", "-c", "echo 'Starting Phosphat Report Application...' && npx prisma db push --accept-data-loss && echo 'Seeding database...' && (test -f scripts/seed-production.js && node scripts/seed-production.js || test -f prisma/seed.js && node prisma/seed.js || echo 'No seeding method available, skipping...') && echo 'Database setup complete. Starting application on port 3000...' && exec npx remix-serve ./build/server/index.js"]
|
CMD ["/app/start.sh"]
|
||||||
@ -3,26 +3,28 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
|
args:
|
||||||
|
- NODE_ENV=production
|
||||||
|
image: phosphat-report:latest
|
||||||
container_name: phosphat-report-app
|
container_name: phosphat-report-app
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "${APP_PORT:-5173}:3000"
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- PORT=3000
|
- PORT=3000
|
||||||
- DATABASE_URL=file:/app/data/production.db
|
- DATABASE_URL=file:/app/data/production.db
|
||||||
- SESSION_SECRET=your-super-secure-session-secret-change-this-min-32-chars
|
- SESSION_SECRET=${SESSION_SECRET}
|
||||||
- SUPER_ADMIN=superadmin
|
- SUPER_ADMIN=${SUPER_ADMIN}
|
||||||
- SUPER_ADMIN_EMAIL=admin@yourcompany.com
|
- SUPER_ADMIN_EMAIL=${SUPER_ADMIN_EMAIL}
|
||||||
- SUPER_ADMIN_PASSWORD=P@ssw0rd123!
|
- SUPER_ADMIN_PASSWORD=${SUPER_ADMIN_PASSWORD}
|
||||||
- MAIL_HOST=smtp.gmail.com
|
- MAIL_HOST=${MAIL_HOST:-}
|
||||||
- MAIL_PORT=587
|
- MAIL_PORT=${MAIL_PORT:-587}
|
||||||
- MAIL_SECURE=false
|
- MAIL_SECURE=${MAIL_SECURE:-false}
|
||||||
- MAIL_USERNAME=your-email@gmail.com
|
- MAIL_USERNAME=${MAIL_USERNAME:-}
|
||||||
- MAIL_PASSWORD=your-app-password
|
- MAIL_PASSWORD=${MAIL_PASSWORD:-}
|
||||||
- MAIL_FROM_NAME=Phosphat Report System
|
- MAIL_FROM_NAME=${MAIL_FROM_NAME:-Phosphat Report System}
|
||||||
- MAIL_FROM_EMAIL=noreply@yourcompany.com
|
- MAIL_FROM_EMAIL=${MAIL_FROM_EMAIL:-}
|
||||||
- ENCRYPTION_KEY=phosphat-report-default-key-32b
|
|
||||||
volumes:
|
volumes:
|
||||||
- app_data:/app/data
|
- app_data:/app/data
|
||||||
- app_logs:/app/logs
|
- app_logs:/app/logs
|
||||||
76
docker-compose.yml
Normal file
76
docker-compose.yml
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
services:
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
args:
|
||||||
|
- NODE_ENV=production
|
||||||
|
image: phosphat-report:latest
|
||||||
|
container_name: phosphat-report-app
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "${APP_PORT:-5173}:3000"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
- PORT=3000
|
||||||
|
- DATABASE_URL=file:/app/data/production.db
|
||||||
|
- SESSION_SECRET=${SESSION_SECRET}
|
||||||
|
- SUPER_ADMIN=${SUPER_ADMIN}
|
||||||
|
- SUPER_ADMIN_EMAIL=${SUPER_ADMIN_EMAIL}
|
||||||
|
- SUPER_ADMIN_PASSWORD=${SUPER_ADMIN_PASSWORD}
|
||||||
|
- MAIL_HOST=${MAIL_HOST:-}
|
||||||
|
- MAIL_PORT=${MAIL_PORT:-587}
|
||||||
|
- MAIL_SECURE=${MAIL_SECURE:-false}
|
||||||
|
- MAIL_USERNAME=${MAIL_USERNAME:-}
|
||||||
|
- MAIL_PASSWORD=${MAIL_PASSWORD:-}
|
||||||
|
- MAIL_FROM_NAME=${MAIL_FROM_NAME:-Phosphat Report System}
|
||||||
|
- MAIL_FROM_EMAIL=${MAIL_FROM_EMAIL:-}
|
||||||
|
volumes:
|
||||||
|
- app_data:/app/data
|
||||||
|
- app_logs:/app/logs
|
||||||
|
networks:
|
||||||
|
- app_network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health", "||", "exit", "1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 512M
|
||||||
|
cpus: '0.5'
|
||||||
|
reservations:
|
||||||
|
memory: 256M
|
||||||
|
cpus: '0.25'
|
||||||
|
|
||||||
|
backup:
|
||||||
|
image: alpine:latest
|
||||||
|
container_name: phosphat-report-backup
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- app_data:/data:ro
|
||||||
|
- backup_data:/backup
|
||||||
|
command: >
|
||||||
|
sh -c "
|
||||||
|
apk add --no-cache dcron sqlite &&
|
||||||
|
echo '0 2 * * * cp /data/production.db /backup/production_$(date +%Y%m%d_%H%M%S).db && find /backup -name \"production_*.db\" -mtime +7 -delete' | crontab - &&
|
||||||
|
crond -f
|
||||||
|
"
|
||||||
|
networks:
|
||||||
|
- app_network
|
||||||
|
depends_on:
|
||||||
|
- app
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
app_data:
|
||||||
|
driver: local
|
||||||
|
app_logs:
|
||||||
|
driver: local
|
||||||
|
backup_data:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
app_network:
|
||||||
|
driver: bridge
|
||||||
BIN
prisma/dev.db
BIN
prisma/dev.db
Binary file not shown.
109
prisma/seed.js
109
prisma/seed.js
@ -6,6 +6,62 @@ const prisma = new PrismaClient();
|
|||||||
async function main() {
|
async function main() {
|
||||||
console.log('🌱 Seeding database...');
|
console.log('🌱 Seeding database...');
|
||||||
|
|
||||||
|
// Seed Areas
|
||||||
|
const areas = await Promise.all([
|
||||||
|
prisma.area.upsert({
|
||||||
|
where: { name: 'Petra' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'Petra' }
|
||||||
|
}),
|
||||||
|
prisma.area.upsert({
|
||||||
|
where: { name: 'Jarash' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'Jarash' }
|
||||||
|
}),
|
||||||
|
prisma.area.upsert({
|
||||||
|
where: { name: 'Rum' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'Rum' }
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Seed DredgerLocations
|
||||||
|
const dredgerLocations = await Promise.all([
|
||||||
|
prisma.dredgerLocation.upsert({
|
||||||
|
where: { name: 'SP1-1' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'SP1-1', class: 'SP' }
|
||||||
|
}),
|
||||||
|
prisma.dredgerLocation.upsert({
|
||||||
|
where: { name: 'SP1-2' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'SP1-2', class: 'SP' }
|
||||||
|
}),
|
||||||
|
prisma.dredgerLocation.upsert({
|
||||||
|
where: { name: 'C01' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'C01', class: 'C' }
|
||||||
|
}),
|
||||||
|
prisma.dredgerLocation.upsert({
|
||||||
|
where: { name: 'D1' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'D1', class: 'D' }
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Seed ReclamationLocations
|
||||||
|
const reclamationLocations = await Promise.all([
|
||||||
|
prisma.reclamationLocation.upsert({
|
||||||
|
where: { name: 'Eastern Shoreline' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'Eastern Shoreline' }
|
||||||
|
}),
|
||||||
|
prisma.reclamationLocation.upsert({
|
||||||
|
where: { name: 'Western Shoreline' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'Western Shoreline' }
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
// Seed Super Admin Employee
|
// Seed Super Admin Employee
|
||||||
const superAdminUsername = process.env.SUPER_ADMIN || 'superadmin';
|
const superAdminUsername = process.env.SUPER_ADMIN || 'superadmin';
|
||||||
@ -24,12 +80,61 @@ async function main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Seed Foreman
|
||||||
|
await prisma.foreman.upsert({
|
||||||
|
where: { id: 1 },
|
||||||
|
update: {},
|
||||||
|
create: {
|
||||||
|
name: 'John Smith'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Seed Equipment
|
||||||
|
const equipment = await Promise.all([
|
||||||
|
prisma.equipment.upsert({
|
||||||
|
where: { id: 1 },
|
||||||
|
update: {},
|
||||||
|
create: { id: 1, category: 'Dozer', model: 'Dozer6', number: 1 }
|
||||||
|
}),
|
||||||
|
prisma.equipment.upsert({
|
||||||
|
where: { id: 2 },
|
||||||
|
update: {},
|
||||||
|
create: { id: 2, category: 'Dozer', model: 'Dozer6', number: 2 }
|
||||||
|
}),
|
||||||
|
prisma.equipment.upsert({
|
||||||
|
where: { id: 3 },
|
||||||
|
update: {},
|
||||||
|
create: { id: 3, category: 'Dozer', model: 'Dozer7', number: 1 }
|
||||||
|
}),
|
||||||
|
prisma.equipment.upsert({
|
||||||
|
where: { id: 4 },
|
||||||
|
update: {},
|
||||||
|
create: { id: 4, category: 'Dozer', model: 'Dozer8', number: 1 }
|
||||||
|
}),
|
||||||
|
prisma.equipment.upsert({
|
||||||
|
where: { id: 5 },
|
||||||
|
update: {},
|
||||||
|
create: { id: 5, category: 'Loader', model: 'Loader', number: 1 }
|
||||||
|
}),
|
||||||
|
prisma.equipment.upsert({
|
||||||
|
where: { id: 6 },
|
||||||
|
update: {},
|
||||||
|
create: { id: 6, category: 'Excavator', model: 'Exc.', number: 1 }
|
||||||
|
}),
|
||||||
|
prisma.equipment.upsert({
|
||||||
|
where: { id: 7 },
|
||||||
|
update: {},
|
||||||
|
create: { id: 7, category: 'Excavator', model: 'Exc.', number: 9 }
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
console.log('✅ Database seeded successfully!');
|
console.log('✅ Database seeded successfully!');
|
||||||
|
console.log(`Created ${areas.length} areas`);
|
||||||
|
console.log(`Created ${dredgerLocations.length} dredger locations`);
|
||||||
|
console.log(`Created ${reclamationLocations.length} reclamation locations`);
|
||||||
console.log(`Created 1 employee`);
|
console.log(`Created 1 employee`);
|
||||||
|
console.log(`Created 1 foreman`);
|
||||||
|
console.log(`Created ${equipment.length} equipment records`);
|
||||||
}
|
}
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|||||||
122
prisma/seed.ts
122
prisma/seed.ts
@ -6,7 +6,75 @@ const prisma = new PrismaClient()
|
|||||||
async function main() {
|
async function main() {
|
||||||
console.log('🌱 Seeding database...')
|
console.log('🌱 Seeding database...')
|
||||||
|
|
||||||
|
// Seed Areas
|
||||||
|
const areas = await Promise.all([
|
||||||
|
prisma.area.upsert({
|
||||||
|
where: { name: 'Petra' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'Petra' }
|
||||||
|
}),
|
||||||
|
prisma.area.upsert({
|
||||||
|
where: { name: 'Jarash' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'Jarash' }
|
||||||
|
}),
|
||||||
|
prisma.area.upsert({
|
||||||
|
where: { name: 'Rum' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'Rum' }
|
||||||
|
})
|
||||||
|
])
|
||||||
|
|
||||||
|
// Seed DredgerLocations
|
||||||
|
const dredgerLocations = await Promise.all([
|
||||||
|
prisma.dredgerLocation.upsert({
|
||||||
|
where: { name: 'SP1-1' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'SP1-1', class: 'SP' }
|
||||||
|
}),
|
||||||
|
prisma.dredgerLocation.upsert({
|
||||||
|
where: { name: 'SP1-2' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'SP1-2', class: 'SP' }
|
||||||
|
}),
|
||||||
|
prisma.dredgerLocation.upsert({
|
||||||
|
where: { name: 'C01' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'C01', class: 'C' }
|
||||||
|
}),
|
||||||
|
prisma.dredgerLocation.upsert({
|
||||||
|
where: { name: 'D1' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'D1', class: 'D' }
|
||||||
|
})
|
||||||
|
])
|
||||||
|
|
||||||
|
// Seed ReclamationLocations
|
||||||
|
const reclamationLocations = await Promise.all([
|
||||||
|
prisma.reclamationLocation.upsert({
|
||||||
|
where: { name: 'Eastern Shoreline' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'Eastern Shoreline' }
|
||||||
|
}),
|
||||||
|
prisma.reclamationLocation.upsert({
|
||||||
|
where: { name: 'Western Shoreline' },
|
||||||
|
update: {},
|
||||||
|
create: { name: 'Western Shoreline' }
|
||||||
|
})
|
||||||
|
])
|
||||||
|
|
||||||
|
// Seed Employee
|
||||||
|
// const employee = await prisma.employee.upsert({
|
||||||
|
// where: { username: 'superuser' },
|
||||||
|
// update: {},
|
||||||
|
// create: {
|
||||||
|
// name: 'Super Admin User',
|
||||||
|
// authLevel: 3,
|
||||||
|
// username: '',
|
||||||
|
// email: '@gmail.com',
|
||||||
|
// password: bcrypt.hashSync('', 10)
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
// Seed Employee
|
// Seed Employee
|
||||||
//use the .env file SUPER_ADMIN, SUPER_ADMIN_EMAIL and SUPER_ADMIN_PASSWORD
|
//use the .env file SUPER_ADMIN, SUPER_ADMIN_EMAIL and SUPER_ADMIN_PASSWORD
|
||||||
@ -24,9 +92,61 @@ async function main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// Seed Foreman
|
||||||
|
const foreman = await prisma.foreman.upsert({
|
||||||
|
where: { id: 1 },
|
||||||
|
update: {},
|
||||||
|
create: {
|
||||||
|
name: 'John Smith'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Seed Equipment
|
||||||
|
const equipment = await Promise.all([
|
||||||
|
prisma.equipment.upsert({
|
||||||
|
where: { id: 1 },
|
||||||
|
update: {},
|
||||||
|
create: { id: 1, category: 'Dozer', model: 'Dozer6', number: 1 }
|
||||||
|
}),
|
||||||
|
prisma.equipment.upsert({
|
||||||
|
where: { id: 2 },
|
||||||
|
update: {},
|
||||||
|
create: { id: 2, category: 'Dozer', model: 'Dozer6', number: 2 }
|
||||||
|
}),
|
||||||
|
prisma.equipment.upsert({
|
||||||
|
where: { id: 3 },
|
||||||
|
update: {},
|
||||||
|
create: { id: 3, category: 'Dozer', model: 'Dozer7', number: 1 }
|
||||||
|
}),
|
||||||
|
prisma.equipment.upsert({
|
||||||
|
where: { id: 4 },
|
||||||
|
update: {},
|
||||||
|
create: { id: 4, category: 'Dozer', model: 'Dozer8', number: 1 }
|
||||||
|
}),
|
||||||
|
prisma.equipment.upsert({
|
||||||
|
where: { id: 5 },
|
||||||
|
update: {},
|
||||||
|
create: { id: 5, category: 'Loader', model: 'Loader', number: 1 }
|
||||||
|
}),
|
||||||
|
prisma.equipment.upsert({
|
||||||
|
where: { id: 6 },
|
||||||
|
update: {},
|
||||||
|
create: { id: 6, category: 'Excavator', model: 'Exc.', number: 1 }
|
||||||
|
}),
|
||||||
|
prisma.equipment.upsert({
|
||||||
|
where: { id: 7 },
|
||||||
|
update: {},
|
||||||
|
create: { id: 7, category: 'Excavator', model: 'Exc.', number: 9 }
|
||||||
|
})
|
||||||
|
])
|
||||||
|
|
||||||
console.log('✅ Database seeded successfully!')
|
console.log('✅ Database seeded successfully!')
|
||||||
|
console.log(`Created ${areas.length} areas`)
|
||||||
|
console.log(`Created ${dredgerLocations.length} dredger locations`)
|
||||||
|
console.log(`Created ${reclamationLocations.length} reclamation locations`)
|
||||||
|
console.log(`Created 1 employee`)
|
||||||
|
console.log(`Created 1 foreman`)
|
||||||
|
console.log(`Created ${equipment.length} equipment records`)
|
||||||
}
|
}
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|||||||
27
start.sh
27
start.sh
@ -1,27 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "Starting Phosphat Report Application..."
|
|
||||||
|
|
||||||
# Run database migrations
|
|
||||||
echo "Running database migrations..."
|
|
||||||
npx prisma db push --accept-data-loss
|
|
||||||
|
|
||||||
# Run seed using production script
|
|
||||||
echo "Seeding database..."
|
|
||||||
if [ -f "scripts/seed-production.js" ]; then
|
|
||||||
echo "Using production seed script..."
|
|
||||||
node scripts/seed-production.js
|
|
||||||
else
|
|
||||||
echo "Production seed script not found, trying alternative methods..."
|
|
||||||
if [ -f "prisma/seed.js" ]; then
|
|
||||||
echo "Using JavaScript seed file..."
|
|
||||||
node prisma/seed.js
|
|
||||||
else
|
|
||||||
echo "No seeding method available, skipping..."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Database setup complete. Starting application on port 3000..."
|
|
||||||
export PORT=3000
|
|
||||||
exec npx remix-serve ./build/server/index.js
|
|
||||||
Loading…
Reference in New Issue
Block a user