chore(markdown): Adding main README and docs/software_requirements_specification.md
This commit is contained in:
131
README.md
Normal file
131
README.md
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
# GoETAAPI
|
||||||
|
|
||||||
|
This repository contains the backend API and database layer for **ETA Viaporte** — a logistics marketplace platform.
|
||||||
|
|
||||||
|
> The project is currently at the **database design and infrastructure** stage. The sections below describe what is available and how to work with it.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Repository Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
GoETAAPI/
|
||||||
|
├── app/ # Go API source (in progress)
|
||||||
|
└── db/
|
||||||
|
├── Models/ # Schema design files (MySQL Workbench + SQL scripts)
|
||||||
|
├── container/ # Dockerfile for the MariaDB test container
|
||||||
|
└── service/ # Docker Compose + Makefile for local deployment
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## DB
|
||||||
|
|
||||||
|
### Schema Design
|
||||||
|
|
||||||
|
The database schema is defined under `db/Models/` and targets the schema `u947463964_etaviaporte`.
|
||||||
|
|
||||||
|
| File | Description |
|
||||||
|
|---|---|
|
||||||
|
| `db/Models/eta_rbac.mwb` | MySQL Workbench model — open this to visualize the full schema diagram |
|
||||||
|
| `db/Models/schemas/eta_rbac.sql` | Forward-engineered SQL schema (generated from the `.mwb` model) |
|
||||||
|
| `db/Models/init/eta_rbac_init.sql` | Seed / initialization data |
|
||||||
|
| `db/Models/eta_rbac_requirements.md` | Human-readable data requirements derived from the schema constraints |
|
||||||
|
|
||||||
|
To inspect or modify the schema visually, open `db/Models/eta_rbac.mwb` with **MySQL Workbench**.
|
||||||
|
|
||||||
|
The schema covers:
|
||||||
|
- **Users & Authentication** — `users`, `auth_identities`, `verification_tokens`, `sessions`
|
||||||
|
- **RBAC** — `applications`, `roles`, `permissions`, `role_permissions`, `user_roles`
|
||||||
|
- **Companies & Locations** — `companies`, `locations`
|
||||||
|
- **Loads & Shipments** — `loads`, `vehicles`, `shipment_proposals`, `shipment_agreements`, `load_shipments`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Docker Container
|
||||||
|
|
||||||
|
The image is built from `db/container/Dockerfile`. It uses **Alpine + MariaDB** and automatically generates a root password on first run. SQL files placed in `/docker-entrypoint-initdb.d` inside the container are executed on startup.
|
||||||
|
|
||||||
|
#### Build the image
|
||||||
|
|
||||||
|
Run from `db/container/`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker buildx build -t eta/eta-db .
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Run the container (basic)
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker run --name eta-db -d -p 3306:3306 eta/eta-db
|
||||||
|
docker logs -f eta-db # root password is printed here on first boot
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Run the container with a named database and user
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker run --name eta-db \
|
||||||
|
-e MYSQL_DATABASE=u947463964_etaviaporte \
|
||||||
|
-e MYSQL_USER=etaapi \
|
||||||
|
-e MYSQL_PASSWORD="secret_password" \
|
||||||
|
-d -p 3306:3306 eta/eta-db
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Run with schema initialization scripts
|
||||||
|
|
||||||
|
Mount a directory of `.sql` files into `/docker-entrypoint-initdb.d` and they will be executed in order on first start:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker run --name eta-db \
|
||||||
|
-e MYSQL_DATABASE=u947463964_etaviaporte \
|
||||||
|
-e MYSQL_USER=etaapi \
|
||||||
|
-e MYSQL_PASSWORD="secret_password" \
|
||||||
|
-v ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d \
|
||||||
|
-d -p 3306:3306 eta/eta-db
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note:** Avoid using `"` (double quotes) in SQL scripts — use `'` (single quotes) instead. Inline comments at the end of SQL statements may also cause parsing errors.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Docker Compose (local testing)
|
||||||
|
|
||||||
|
`db/service/compose.yml` deploys the `eta/eta-db` image with the schema and seed data pre-loaded. It mounts `db/service/initdb/` into the container's init directory.
|
||||||
|
|
||||||
|
Before deploying with Compose, populate `db/service/initdb/` by running `make prepare` (see below), then start the service:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd db/service
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
The service exposes MariaDB on port `3306` with:
|
||||||
|
|
||||||
|
| Variable | Value |
|
||||||
|
|---|---|
|
||||||
|
| `MYSQL_DATABASE` | `u947463964_etaviaporte` |
|
||||||
|
| `MYSQL_USER` | `etaapi` |
|
||||||
|
| `MYSQL_PASSWORD` | `secret_password` |
|
||||||
|
|
||||||
|
> The `initdb/` volume uses the `:Z` SELinux label to avoid permission denied errors on SELinux-enabled systems.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Makefile — Prepare init scripts
|
||||||
|
|
||||||
|
The `db/service/Makefile` copies the latest schema and seed files from `db/Models/` into `db/service/initdb/`, so they are picked up by Docker Compose on the next container start.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd db/service
|
||||||
|
make prepare
|
||||||
|
```
|
||||||
|
|
||||||
|
This runs:
|
||||||
|
1. Clears any existing `.sql` files from `db/service/initdb/`.
|
||||||
|
2. Copies `db/Models/schemas/eta_rbac.sql` → `initdb/00-schema.sql`
|
||||||
|
3. Copies `db/Models/init/eta_rbac_init.sql` → `initdb/01-initdb.sql`
|
||||||
|
|
||||||
|
Always run `make prepare` after updating the schema model before bringing the Compose service up.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 221 KiB |
Binary file not shown.
@@ -1,18 +0,0 @@
|
|||||||
-- Creation of root and backoffice
|
|
||||||
INSERT INTO applications (name, slug, description) VALUES ('root/backoffice','root_backoffice',"This is the application with no restrictions to all resources");
|
|
||||||
|
|
||||||
INSERT INTO permissions (application_id, name, description) VALUES (1, 'root', "No restrictions");
|
|
||||||
|
|
||||||
INSERT INTO roles (application_id, name, description) VALUES (1, 'root', "No restrictions");
|
|
||||||
|
|
||||||
INSERT INTO role_permissions (role_id, permission_id) VALUES (1,1);
|
|
||||||
|
|
||||||
INSERT INTO users (name, last_name) VALUES ('root','root');
|
|
||||||
|
|
||||||
INSERT INTO auth_identities (user_id, provider, identifier, password_hash, is_primary, is_verified) VALUES (1,'email','root@root.com','invalid_password_hash',1,1);
|
|
||||||
|
|
||||||
INSERT INTO user_roles (user_id, role_id) VALUES (1,1);
|
|
||||||
|
|
||||||
INSERT INTO user_permissions (user_id, permission_id) VALUES (1,1);
|
|
||||||
|
|
||||||
INSERT INTO user_applications (user_id, application_id) VALUES (1,1);
|
|
||||||
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
-- MySQL Script generated by MySQL Workbench
|
-- MySQL Script generated by MySQL Workbench
|
||||||
-- Thu 02 Apr 2026 01:32:42 AM CST
|
-- Mon 06 Apr 2026 02:56:46 PM CST
|
||||||
-- Model: New Model Version: 1.0
|
-- Model: New Model Version: 1.0
|
||||||
-- MySQL Workbench Forward Engineering
|
-- MySQL Workbench Forward Engineering
|
||||||
|
|
||||||
@@ -193,6 +193,7 @@ ENGINE = InnoDB;
|
|||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`sessions` (
|
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`sessions` (
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`application_id` INT UNSIGNED NOT NULL,
|
||||||
`user_id` INT UNSIGNED NOT NULL,
|
`user_id` INT UNSIGNED NOT NULL,
|
||||||
`session_token_hash` VARCHAR(255) NOT NULL,
|
`session_token_hash` VARCHAR(255) NOT NULL,
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
@@ -202,10 +203,16 @@ CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`sessions` (
|
|||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
INDEX `fk_sessions_users1_idx` (`user_id` ASC) VISIBLE,
|
INDEX `fk_sessions_users1_idx` (`user_id` ASC) VISIBLE,
|
||||||
UNIQUE INDEX `session_token_hash_UNIQUE` (`session_token_hash` ASC) VISIBLE,
|
UNIQUE INDEX `session_token_hash_UNIQUE` (`session_token_hash` ASC) VISIBLE,
|
||||||
|
INDEX `fk_sessions_applications1_idx` (`application_id` ASC) VISIBLE,
|
||||||
CONSTRAINT `fk_sessions_users1`
|
CONSTRAINT `fk_sessions_users1`
|
||||||
FOREIGN KEY (`user_id`)
|
FOREIGN KEY (`user_id`)
|
||||||
REFERENCES `u947463964_etaviaporte`.`users` (`id`)
|
REFERENCES `u947463964_etaviaporte`.`users` (`id`)
|
||||||
ON DELETE CASCADE
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE NO ACTION,
|
||||||
|
CONSTRAINT `fk_sessions_applications1`
|
||||||
|
FOREIGN KEY (`application_id`)
|
||||||
|
REFERENCES `u947463964_etaviaporte`.`applications` (`id`)
|
||||||
|
ON DELETE CASCADE
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
ENGINE = InnoDB;
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|||||||
@@ -1,289 +0,0 @@
|
|||||||
-- MySQL Script generated by MySQL Workbench
|
|
||||||
-- Tue 31 Mar 2026 11:55:20 PM CST
|
|
||||||
-- Model: New Model Version: 1.0
|
|
||||||
-- MySQL Workbench Forward Engineering
|
|
||||||
|
|
||||||
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
|
|
||||||
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
|
|
||||||
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
-- Schema u947463964_etaviaporte
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
-- Schema u947463964_etaviaporte
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
CREATE SCHEMA IF NOT EXISTS `u947463964_etaviaporte` DEFAULT CHARACTER SET utf8 ;
|
|
||||||
USE `u947463964_etaviaporte` ;
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
-- Table `u947463964_etaviaporte`.`users`
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`users` (
|
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
`name` VARCHAR(512) NOT NULL,
|
|
||||||
`last_name` VARCHAR(512) NOT NULL,
|
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
||||||
PRIMARY KEY (`id`))
|
|
||||||
ENGINE = InnoDB;
|
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
-- Table `u947463964_etaviaporte`.`auth_identities`
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`auth_identities` (
|
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
`user_id` INT UNSIGNED NOT NULL,
|
|
||||||
`provider` VARCHAR(512) NOT NULL COMMENT 'type of identifier: email, phone, etc',
|
|
||||||
`identifier` VARCHAR(512) COLLATE 'Default Collation' NOT NULL COMMENT 'email, phone google, facebook, etc.',
|
|
||||||
`password_hash` VARCHAR(512) COLLATE 'Default Collation' NULL COMMENT 'password for phone or email',
|
|
||||||
`is_primary` TINYINT NOT NULL DEFAULT 0,
|
|
||||||
`is_verified` TINYINT NOT NULL DEFAULT 0,
|
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'when phone or email, password goes here.',
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
INDEX `fk_auth_identities_users_idx` (`user_id` ASC) VISIBLE,
|
|
||||||
UNIQUE INDEX `provider_UNIQUE` (`provider` ASC, `identifier` ASC) VISIBLE,
|
|
||||||
CONSTRAINT `fk_auth_identities_users`
|
|
||||||
FOREIGN KEY (`user_id`)
|
|
||||||
REFERENCES `u947463964_etaviaporte`.`users` (`id`)
|
|
||||||
ON DELETE CASCADE
|
|
||||||
ON UPDATE NO ACTION)
|
|
||||||
ENGINE = InnoDB;
|
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
-- Table `u947463964_etaviaporte`.`applications`
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`applications` (
|
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
`name` VARCHAR(512) NOT NULL,
|
|
||||||
`slug` VARCHAR(512) NOT NULL,
|
|
||||||
`description` TEXT NULL,
|
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
UNIQUE INDEX `slug_UNIQUE` (`slug` ASC) VISIBLE,
|
|
||||||
UNIQUE INDEX `name_UNIQUE` (`name` ASC) VISIBLE)
|
|
||||||
ENGINE = InnoDB;
|
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
-- Table `u947463964_etaviaporte`.`roles`
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`roles` (
|
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
`application_id` INT UNSIGNED NOT NULL,
|
|
||||||
`name` VARCHAR(512) NOT NULL,
|
|
||||||
`description` TEXT NULL,
|
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
UNIQUE INDEX `name_UNIQUE` (`application_id` ASC, `name` ASC) VISIBLE,
|
|
||||||
INDEX `fk_roles_applications1_idx` (`application_id` ASC) VISIBLE,
|
|
||||||
CONSTRAINT `fk_roles_applications1`
|
|
||||||
FOREIGN KEY (`application_id`)
|
|
||||||
REFERENCES `u947463964_etaviaporte`.`applications` (`id`)
|
|
||||||
ON DELETE NO ACTION
|
|
||||||
ON UPDATE NO ACTION)
|
|
||||||
ENGINE = InnoDB;
|
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
-- Table `u947463964_etaviaporte`.`permissions`
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`permissions` (
|
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
`application_id` INT UNSIGNED NOT NULL,
|
|
||||||
`name` VARCHAR(512) NOT NULL,
|
|
||||||
`description` TEXT NULL,
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
UNIQUE INDEX `name_UNIQUE` (`application_id` ASC, `name` ASC) VISIBLE,
|
|
||||||
INDEX `fk_permissions_applications1_idx` (`application_id` ASC) VISIBLE,
|
|
||||||
CONSTRAINT `fk_permissions_applications1`
|
|
||||||
FOREIGN KEY (`application_id`)
|
|
||||||
REFERENCES `u947463964_etaviaporte`.`applications` (`id`)
|
|
||||||
ON DELETE NO ACTION
|
|
||||||
ON UPDATE NO ACTION)
|
|
||||||
ENGINE = InnoDB;
|
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
-- Table `u947463964_etaviaporte`.`role_permissions`
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`role_permissions` (
|
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
`role_id` INT UNSIGNED NOT NULL,
|
|
||||||
`permission_id` INT UNSIGNED NOT NULL,
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
INDEX `fk_role_permissions_roles1_idx` (`role_id` ASC) VISIBLE,
|
|
||||||
INDEX `fk_role_permissions_permissions1_idx` (`permission_id` ASC) VISIBLE,
|
|
||||||
UNIQUE INDEX `role_id_UNIQUE` (`role_id` ASC, `permission_id` ASC) VISIBLE,
|
|
||||||
CONSTRAINT `fk_role_permissions_roles1`
|
|
||||||
FOREIGN KEY (`role_id`)
|
|
||||||
REFERENCES `u947463964_etaviaporte`.`roles` (`id`)
|
|
||||||
ON DELETE CASCADE
|
|
||||||
ON UPDATE NO ACTION,
|
|
||||||
CONSTRAINT `fk_role_permissions_permissions1`
|
|
||||||
FOREIGN KEY (`permission_id`)
|
|
||||||
REFERENCES `u947463964_etaviaporte`.`permissions` (`id`)
|
|
||||||
ON DELETE CASCADE
|
|
||||||
ON UPDATE NO ACTION)
|
|
||||||
ENGINE = InnoDB;
|
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
-- Table `u947463964_etaviaporte`.`user_roles`
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`user_roles` (
|
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
`user_id` INT UNSIGNED NOT NULL,
|
|
||||||
`role_id` INT UNSIGNED NOT NULL,
|
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
`expires_at` DATETIME NULL,
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
INDEX `fk_user_roles_users1_idx` (`user_id` ASC) VISIBLE,
|
|
||||||
INDEX `fk_user_roles_roles1_idx` (`role_id` ASC) VISIBLE,
|
|
||||||
UNIQUE INDEX `user_id_UNIQUE` (`user_id` ASC, `role_id` ASC) VISIBLE,
|
|
||||||
CONSTRAINT `fk_user_roles_users1`
|
|
||||||
FOREIGN KEY (`user_id`)
|
|
||||||
REFERENCES `u947463964_etaviaporte`.`users` (`id`)
|
|
||||||
ON DELETE CASCADE
|
|
||||||
ON UPDATE NO ACTION,
|
|
||||||
CONSTRAINT `fk_user_roles_roles1`
|
|
||||||
FOREIGN KEY (`role_id`)
|
|
||||||
REFERENCES `u947463964_etaviaporte`.`roles` (`id`)
|
|
||||||
ON DELETE CASCADE
|
|
||||||
ON UPDATE NO ACTION)
|
|
||||||
ENGINE = InnoDB;
|
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
-- Table `u947463964_etaviaporte`.`user_permissions`
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`user_permissions` (
|
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
`user_id` INT UNSIGNED NOT NULL,
|
|
||||||
`permission_id` INT UNSIGNED NOT NULL,
|
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
`expires_at` DATETIME NULL,
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
INDEX `fk_user_permissions_permissions1_idx` (`permission_id` ASC) VISIBLE,
|
|
||||||
INDEX `fk_user_permissions_users1_idx` (`user_id` ASC) VISIBLE,
|
|
||||||
UNIQUE INDEX `user_id_UNIQUE` (`user_id` ASC, `permission_id` ASC) VISIBLE,
|
|
||||||
CONSTRAINT `fk_user_permissions_permissions1`
|
|
||||||
FOREIGN KEY (`permission_id`)
|
|
||||||
REFERENCES `u947463964_etaviaporte`.`permissions` (`id`)
|
|
||||||
ON DELETE CASCADE
|
|
||||||
ON UPDATE NO ACTION,
|
|
||||||
CONSTRAINT `fk_user_permissions_users1`
|
|
||||||
FOREIGN KEY (`user_id`)
|
|
||||||
REFERENCES `u947463964_etaviaporte`.`users` (`id`)
|
|
||||||
ON DELETE CASCADE
|
|
||||||
ON UPDATE NO ACTION)
|
|
||||||
ENGINE = InnoDB;
|
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
-- Table `u947463964_etaviaporte`.`verification_tokens`
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`verification_tokens` (
|
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
`auth_identity_id` INT UNSIGNED NOT NULL,
|
|
||||||
`token_hash` VARCHAR(255) NOT NULL COMMENT 'Verification token for email/phone/notification mechanisms to either validate or reset passwords',
|
|
||||||
`purpose` ENUM('email_verification', 'phone_verification', 'password_reset') NOT NULL,
|
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
`expires_at` DATETIME NOT NULL,
|
|
||||||
`used_at` DATETIME NULL,
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
INDEX `fk_verification_tokens_auth_identities1_idx` (`auth_identity_id` ASC) VISIBLE,
|
|
||||||
UNIQUE INDEX `token_hash_UNIQUE` (`token_hash` ASC) VISIBLE,
|
|
||||||
CONSTRAINT `fk_verification_tokens_auth_identities1`
|
|
||||||
FOREIGN KEY (`auth_identity_id`)
|
|
||||||
REFERENCES `u947463964_etaviaporte`.`auth_identities` (`id`)
|
|
||||||
ON DELETE CASCADE
|
|
||||||
ON UPDATE NO ACTION)
|
|
||||||
ENGINE = InnoDB;
|
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
-- Table `u947463964_etaviaporte`.`sessions`
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`sessions` (
|
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
`user_id` INT UNSIGNED NOT NULL,
|
|
||||||
`application_id` INT UNSIGNED NOT NULL,
|
|
||||||
`session_token_hash` VARCHAR(255) NOT NULL,
|
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
||||||
`expires_at` DATETIME NOT NULL,
|
|
||||||
`revoked_at` DATETIME NULL,
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
INDEX `fk_sessions_users1_idx` (`user_id` ASC) VISIBLE,
|
|
||||||
UNIQUE INDEX `session_token_hash_UNIQUE` (`application_id` ASC, `session_token_hash` ASC) VISIBLE,
|
|
||||||
INDEX `fk_sessions_applications1_idx` (`application_id` ASC) VISIBLE,
|
|
||||||
CONSTRAINT `fk_sessions_users1`
|
|
||||||
FOREIGN KEY (`user_id`)
|
|
||||||
REFERENCES `u947463964_etaviaporte`.`users` (`id`)
|
|
||||||
ON DELETE CASCADE
|
|
||||||
ON UPDATE NO ACTION,
|
|
||||||
CONSTRAINT `fk_sessions_applications1`
|
|
||||||
FOREIGN KEY (`application_id`)
|
|
||||||
REFERENCES `u947463964_etaviaporte`.`applications` (`id`)
|
|
||||||
ON DELETE NO ACTION
|
|
||||||
ON UPDATE NO ACTION)
|
|
||||||
ENGINE = InnoDB;
|
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
-- Table `u947463964_etaviaporte`.`user_applications`
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`user_applications` (
|
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
`user_id` INT UNSIGNED NOT NULL,
|
|
||||||
`application_id` INT UNSIGNED NOT NULL,
|
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
INDEX `fk_user_application_users1_idx` (`user_id` ASC) VISIBLE,
|
|
||||||
INDEX `fk_user_application_applications1_idx` (`application_id` ASC) VISIBLE,
|
|
||||||
UNIQUE INDEX `user_id_UNIQUE` (`user_id` ASC, `application_id` ASC) VISIBLE,
|
|
||||||
CONSTRAINT `fk_user_application_users1`
|
|
||||||
FOREIGN KEY (`user_id`)
|
|
||||||
REFERENCES `u947463964_etaviaporte`.`users` (`id`)
|
|
||||||
ON DELETE CASCADE
|
|
||||||
ON UPDATE NO ACTION,
|
|
||||||
CONSTRAINT `fk_user_application_applications1`
|
|
||||||
FOREIGN KEY (`application_id`)
|
|
||||||
REFERENCES `u947463964_etaviaporte`.`applications` (`id`)
|
|
||||||
ON DELETE CASCADE
|
|
||||||
ON UPDATE NO ACTION)
|
|
||||||
ENGINE = InnoDB;
|
|
||||||
|
|
||||||
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
-- Table `u947463964_etaviaporte`.`api_keys`
|
|
||||||
-- -----------------------------------------------------
|
|
||||||
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`api_keys` (
|
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
||||||
`application_id` INT UNSIGNED NOT NULL,
|
|
||||||
`name` VARCHAR(512) NOT NULL,
|
|
||||||
`description` TEXT NULL,
|
|
||||||
`key_hash` VARCHAR(255) NOT NULL,
|
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
`expires_at` DATETIME NULL,
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
UNIQUE INDEX `key_hash_UNIQUE` (`key_hash` ASC) VISIBLE,
|
|
||||||
INDEX `fk_api_keys_applications1_idx` (`application_id` ASC) VISIBLE,
|
|
||||||
CONSTRAINT `fk_api_keys_applications1`
|
|
||||||
FOREIGN KEY (`application_id`)
|
|
||||||
REFERENCES `u947463964_etaviaporte`.`applications` (`id`)
|
|
||||||
ON DELETE CASCADE
|
|
||||||
ON UPDATE NO ACTION)
|
|
||||||
ENGINE = InnoDB;
|
|
||||||
|
|
||||||
|
|
||||||
SET SQL_MODE=@OLD_SQL_MODE;
|
|
||||||
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
|
||||||
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
-- MySQL Script generated by MySQL Workbench
|
-- MySQL Script generated by MySQL Workbench
|
||||||
-- Thu 02 Apr 2026 01:32:42 AM CST
|
-- Mon 06 Apr 2026 02:56:46 PM CST
|
||||||
-- Model: New Model Version: 1.0
|
-- Model: New Model Version: 1.0
|
||||||
-- MySQL Workbench Forward Engineering
|
-- MySQL Workbench Forward Engineering
|
||||||
|
|
||||||
@@ -193,6 +193,7 @@ ENGINE = InnoDB;
|
|||||||
-- -----------------------------------------------------
|
-- -----------------------------------------------------
|
||||||
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`sessions` (
|
CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`sessions` (
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`application_id` INT UNSIGNED NOT NULL,
|
||||||
`user_id` INT UNSIGNED NOT NULL,
|
`user_id` INT UNSIGNED NOT NULL,
|
||||||
`session_token_hash` VARCHAR(255) NOT NULL,
|
`session_token_hash` VARCHAR(255) NOT NULL,
|
||||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
@@ -202,10 +203,16 @@ CREATE TABLE IF NOT EXISTS `u947463964_etaviaporte`.`sessions` (
|
|||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
INDEX `fk_sessions_users1_idx` (`user_id` ASC) VISIBLE,
|
INDEX `fk_sessions_users1_idx` (`user_id` ASC) VISIBLE,
|
||||||
UNIQUE INDEX `session_token_hash_UNIQUE` (`session_token_hash` ASC) VISIBLE,
|
UNIQUE INDEX `session_token_hash_UNIQUE` (`session_token_hash` ASC) VISIBLE,
|
||||||
|
INDEX `fk_sessions_applications1_idx` (`application_id` ASC) VISIBLE,
|
||||||
CONSTRAINT `fk_sessions_users1`
|
CONSTRAINT `fk_sessions_users1`
|
||||||
FOREIGN KEY (`user_id`)
|
FOREIGN KEY (`user_id`)
|
||||||
REFERENCES `u947463964_etaviaporte`.`users` (`id`)
|
REFERENCES `u947463964_etaviaporte`.`users` (`id`)
|
||||||
ON DELETE CASCADE
|
ON DELETE CASCADE
|
||||||
|
ON UPDATE NO ACTION,
|
||||||
|
CONSTRAINT `fk_sessions_applications1`
|
||||||
|
FOREIGN KEY (`application_id`)
|
||||||
|
REFERENCES `u947463964_etaviaporte`.`applications` (`id`)
|
||||||
|
ON DELETE CASCADE
|
||||||
ON UPDATE NO ACTION)
|
ON UPDATE NO ACTION)
|
||||||
ENGINE = InnoDB;
|
ENGINE = InnoDB;
|
||||||
|
|
||||||
|
|||||||
117
docs/software_requirements_specification.md
Normal file
117
docs/software_requirements_specification.md
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
# ETA's Core API
|
||||||
|
|
||||||
|
Draft of software requirements specification (SRS) to model API endpoints and its responsabilities.
|
||||||
|
|
||||||
|
- **/meta/applications**:
|
||||||
|
- **Operations**:
|
||||||
|
- Create application. (idempotency through client UUID)
|
||||||
|
- Read applications
|
||||||
|
- Update applications
|
||||||
|
- Delete applications
|
||||||
|
|
||||||
|
- **/apps/{app_id}/roles**:
|
||||||
|
- **Operations**:
|
||||||
|
- Create application roles. (idempotency through client UUID)
|
||||||
|
- Read application roles
|
||||||
|
- Update application roles
|
||||||
|
- Delete application roles
|
||||||
|
|
||||||
|
- **/apps/{app_id}/permissions**:
|
||||||
|
- **Operations**:
|
||||||
|
- Create application permissions. (idempotency through client UUID)
|
||||||
|
- Read application permissions
|
||||||
|
- Update application permissions
|
||||||
|
- Delete application permissions
|
||||||
|
|
||||||
|
- **/apps/{app_id}/users/{user_id}/roles**:
|
||||||
|
- **Operations**:
|
||||||
|
- Assign roles to user
|
||||||
|
- Delete roles from user
|
||||||
|
- Read roles from user
|
||||||
|
|
||||||
|
- **/apps/{app_id}/users/{user_id}/permissions**:
|
||||||
|
- **Operations**:
|
||||||
|
- Assign permission to user
|
||||||
|
- Delete permission to user
|
||||||
|
- Read permissions assigned to user
|
||||||
|
|
||||||
|
- **/apps/{app_id}/users/{user_id}/apikeys**:
|
||||||
|
- **Operations**:
|
||||||
|
- Create apikeys. (idempotency through client UUID)
|
||||||
|
- Read apikeys
|
||||||
|
- Delete apikeys
|
||||||
|
|
||||||
|
- **/apps/{app_id}/auth**:
|
||||||
|
- **Operations**:
|
||||||
|
- Manage authentication of user:
|
||||||
|
- **/app/{app_id}/auth/identity/[phone,email]**:
|
||||||
|
- Identify user and return JWT.
|
||||||
|
- Create user and assign to application. (idempotency through client UUID)
|
||||||
|
- **/app/{app_id}/auth/identity/[phone,email]/verify**:
|
||||||
|
- Verify identity and assign to application. (idempotency through client UUID)
|
||||||
|
- **/app/{app_id}/auth/logout**:
|
||||||
|
- **/app/{app_id}/auth/refresh**:
|
||||||
|
- **/app/{app_id}/auth/me**:
|
||||||
|
|
||||||
|
# Admin Authorization Strategy:
|
||||||
|
|
||||||
|
The system shall have a predefined system application to control all resources.
|
||||||
|
|
||||||
|
The system application can't be removed.
|
||||||
|
|
||||||
|
The system application shall have predefined permissions and roles to control the access to all resources at different granularity levels:
|
||||||
|
- CRUD of applications.
|
||||||
|
- CRUD of applications' roles.
|
||||||
|
- CRUD of applications' permissions.
|
||||||
|
- CRUD of applications' users.
|
||||||
|
- CRUD of applications' apikeys.
|
||||||
|
- etc.
|
||||||
|
|
||||||
|
The system application shall have an admin user with only apikeys and no identities.
|
||||||
|
|
||||||
|
The system application's admin user shall have permissions assigned to manage applications.
|
||||||
|
|
||||||
|
The system application's admin user shall have permissions assigned to manage users.
|
||||||
|
|
||||||
|
The system application's admin user shall have permissions assigned to manage roles and permissions within applications.
|
||||||
|
|
||||||
|
The system application's admin user shall have permissions assigned to manage apikeys within applications.
|
||||||
|
|
||||||
|
The system application's admin user shall not have full control over the system resources.* (No other resource than users, roles, permissions)
|
||||||
|
|
||||||
|
Every application shall have an admin user with only apikeys and no identities.
|
||||||
|
|
||||||
|
Every application shall have an admin user to manage application resources.
|
||||||
|
|
||||||
|
Every application shall have an admin user to manage users within applications:
|
||||||
|
|
||||||
|
- Shall allow assigning or removing existing users to/from applications.
|
||||||
|
- Shall allow create and assign users to applications.
|
||||||
|
|
||||||
|
The application's admin user shall not have full control over the application resources.* (No other resource than users, roles, permissions)
|
||||||
|
|
||||||
|
Every application shall have it's own API that serves as an API wrapper to consume system resources.
|
||||||
|
|
||||||
|
Every application shall have it's own API that serves as an API wrapper to consume application resources.
|
||||||
|
|
||||||
|
Every application specific API shall use the user's authorization token or apikey to consume application's resources.
|
||||||
|
|
||||||
|
(Admin Portal shall have it's own API that communicates with the core API to manage system resources associated to the system and the application components).
|
||||||
|
|
||||||
|
(Admin Portal shall have it's own API key to only create users and assign roles to it).
|
||||||
|
|
||||||
|
(Admin Portal shall modify system resources by the usage of a JWT of an identified user to enable audit logs of resources manipulation).
|
||||||
|
|
||||||
|
# Idempotency Strategy:
|
||||||
|
|
||||||
|
When a resource requires "idempotency", the HTTP header `X-Idempotency-Key` must be provided with an UUID generated from the client.
|
||||||
|
|
||||||
|
# Authorization Tokens (Core API):
|
||||||
|
|
||||||
|
When API Key is used, the HTTP header `x-api-key: <apikey>` shall be used.*
|
||||||
|
|
||||||
|
When JWT is used, the HTTP header `Authorization: Bearer <jwt>` shall be used.
|
||||||
|
|
||||||
|
When JWT refresh is used, the HTTP header `x-refresh-token: <refresh_token>` shall be used.
|
||||||
|
|
||||||
|
Every application's specific API (also known as API wrapper) shall use it's own authorization mechanisms.
|
||||||
Reference in New Issue
Block a user