Use firstOrCreate instead of create so db:seed can run safely on container restart without duplicate key violation.
132 lines
4.5 KiB
Markdown
132 lines
4.5 KiB
Markdown
# Database Schema
|
|
|
|
## Tables
|
|
|
|
### `station`
|
|
|
|
Primary table storing telemetry station metadata.
|
|
|
|
| Column | Type | Description |
|
|
|--------|------|-------------|
|
|
| `stationid` | `varchar` (PK) | Unique station identifier (e.g., "KBLG0026") |
|
|
| `name` | `varchar(255)` | Station display name |
|
|
| `district` | `varchar(255)` | District location |
|
|
| `lng` | `float` | Longitude coordinate |
|
|
| `lat` | `float` | Latitude coordinate |
|
|
| `mainriverbasin` | `varchar(255)` | Main river basin name |
|
|
| `subriverbasin` | `varchar(255)` | Sub river basin name |
|
|
| `rainfall` | `integer` | Has rainfall sensor (1=yes, 0=no) |
|
|
| `waterlevel` | `integer` | Has water level sensor (1=yes, 0=no) |
|
|
| `siren` | `integer` (nullable) | Has siren (1=yes, 0=no) |
|
|
| `cctv_link` | `varchar(500)` (nullable) | URL to CCTV feed |
|
|
|
|
### `rainfall`
|
|
|
|
Stores rainfall readings from telemetry stations.
|
|
|
|
| Column | Type | Description |
|
|
|--------|------|-------------|
|
|
| `id` | `bigint` (PK, auto) | Auto-increment ID |
|
|
| `stationid` | `varchar` | Station identifier (FK to station) |
|
|
| `timestamp` | `timestamp` | Reading timestamp |
|
|
| `anncum` | `double` | Annual cumulative rainfall |
|
|
| `daily` | `double` | Daily cumulative rainfall |
|
|
| `hourly` | `double` | Hourly rainfall |
|
|
| `currentrf` | `double` | Current rainfall |
|
|
| `battery` | `double` | Battery voltage |
|
|
|
|
### `waterlevel`
|
|
|
|
Stores water level readings with threshold values.
|
|
|
|
| Column | Type | Description |
|
|
|--------|------|-------------|
|
|
| `id` | `bigint` (PK, auto) | Auto-increment ID |
|
|
| `stationid` | `varchar` | Station identifier (FK to station) |
|
|
| `datetime` | `timestamp` | Reading timestamp |
|
|
| `waterlevel` | `double` | Current water level (meters) |
|
|
| `alert` | `double` | Alert threshold level |
|
|
| `warning` | `double` | Warning threshold level |
|
|
| `danger` | `double` | Danger threshold level |
|
|
|
|
### `siren`
|
|
|
|
Stores siren activation records.
|
|
|
|
| Column | Type | Description |
|
|
|--------|------|-------------|
|
|
| `id` | `bigint` (PK, auto) | Auto-increment ID |
|
|
| `stationid` | `varchar` | Station identifier (FK to station) |
|
|
| `stationtype` | `varchar` | Station type identifier |
|
|
| `active_time` | `timestamp` | Siren activation time |
|
|
| `level` | `varchar` | Siren level (`H`=Danger, `L`=Warning, `N`=Normal) |
|
|
|
|
### `notification`
|
|
|
|
Stores threshold-exceeded alert records.
|
|
|
|
| Column | Type | Description |
|
|
|--------|------|-------------|
|
|
| `id` | `bigint` (PK, auto) | Auto-increment ID |
|
|
| `stationid` | `varchar` | Station identifier (FK to station) |
|
|
| `timestamp` | `timestamp` | Alert timestamp |
|
|
| `stationtype` | `integer` | Type: 1=rainfall, 2=waterlevel, 3=siren |
|
|
| `level` | `varchar` | Alert level (Alert, Warning, Danger) |
|
|
| `active_time` | `timestamp` (nullable) | Activation time |
|
|
|
|
### `users`
|
|
|
|
Stores application users.
|
|
|
|
| Column | Type | Description |
|
|
|--------|------|-------------|
|
|
| `id` | `bigint` (PK, auto) | Auto-increment ID |
|
|
| `name` | `varchar(255)` | Username |
|
|
| `email` | `varchar(255)` (unique) | Email address |
|
|
| `email_verified_at` | `timestamp` (nullable) | Email verification timestamp |
|
|
| `password` | `varchar(255)` | Bcrypt-hashed password |
|
|
| `access_level` | `integer` | 1=Admin, 2=User |
|
|
| `is_blocked` | `boolean` | Account blocked status |
|
|
| `login_attempts` | `integer` | Failed login attempt count |
|
|
| `remember_token` | `varchar` | Remember me token |
|
|
| `created_at`, `updated_at` | `timestamp` | Laravel timestamps |
|
|
|
|
### Laravel Standard Tables
|
|
|
|
- `password_reset_tokens` — Password reset tokens
|
|
- `sessions` — Database-backed sessions
|
|
- `cache` / `cache_locks` — Cache store
|
|
- `jobs` / `job_batches` / `failed_jobs` — Queue system
|
|
- `migrations` — Migration tracking
|
|
|
|
## Relationships
|
|
|
|
```
|
|
station (1) ──< (many) rainfall via stationid
|
|
station (1) ──< (many) waterlevel via stationid
|
|
station (1) ──< (many) siren via stationid
|
|
station (1) ──< (many) notification via stationid
|
|
```
|
|
|
|
**Note**: No database-level foreign keys or constraints exist. All relationships are maintained at the application level.
|
|
|
|
## Indexes
|
|
|
|
- `users.email` — unique index
|
|
- `sessions.last_activity` — index
|
|
- `sessions.user_id` — index
|
|
- No additional indexes on data tables (potential performance concern)
|
|
|
|
## Default Data
|
|
|
|
### Default Admin User
|
|
|
|
Created via `DatabaseSeeder` and migration `2025_12_11_124201_add_default_user_to_users_table.php`:
|
|
|
|
- **Username**: `admin` (seeder) / `admin` (migration)
|
|
- **Email**: `admin@example.com`
|
|
- **Password**: `password123`
|
|
- **Access Level**: 1 (Admin)
|
|
|
|
**Note**: The admin user is created in both the seeder AND a migration, which would cause a duplicate key error if both run.
|