Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 47 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ A RESTful API that serves **hierarchical location data** of the Philippines —
[![DeepWiki](https://img.shields.io/badge/DeepWiki-weaponsforge%2Fph--regions-blue.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAyCAYAAAAnWDnqAAAAAXNSR0IArs4c6QAAA05JREFUaEPtmUtyEzEQhtWTQyQLHNak2AB7ZnyXZMEjXMGeK/AIi+QuHrMnbChYY7MIh8g01fJoopFb0uhhEqqcbWTp06/uv1saEDv4O3n3dV60RfP947Mm9/SQc0ICFQgzfc4CYZoTPAswgSJCCUJUnAAoRHOAUOcATwbmVLWdGoH//PB8mnKqScAhsD0kYP3j/Yt5LPQe2KvcXmGvRHcDnpxfL2zOYJ1mFwrryWTz0advv1Ut4CJgf5uhDuDj5eUcAUoahrdY/56ebRWeraTjMt/00Sh3UDtjgHtQNHwcRGOC98BJEAEymycmYcWwOprTgcB6VZ5JK5TAJ+fXGLBm3FDAmn6oPPjR4rKCAoJCal2eAiQp2x0vxTPB3ALO2CRkwmDy5WohzBDwSEFKRwPbknEggCPB/imwrycgxX2NzoMCHhPkDwqYMr9tRcP5qNrMZHkVnOjRMWwLCcr8ohBVb1OMjxLwGCvjTikrsBOiA6fNyCrm8V1rP93iVPpwaE+gO0SsWmPiXB+jikdf6SizrT5qKasx5j8ABbHpFTx+vFXp9EnYQmLx02h1QTTrl6eDqxLnGjporxl3NL3agEvXdT0WmEost648sQOYAeJS9Q7bfUVoMGnjo4AZdUMQku50McDcMWcBPvr0SzbTAFDfvJqwLzgxwATnCgnp4wDl6Aa+Ax283gghmj+vj7feE2KBBRMW3FzOpLOADl0Isb5587h/U4gGvkt5v60Z1VLG8BhYjbzRwyQZemwAd6cCR5/XFWLYZRIMpX39AR0tjaGGiGzLVyhse5C9RKC6ai42ppWPKiBagOvaYk8lO7DajerabOZP46Lby5wKjw1HCRx7p9sVMOWGzb/vA1hwiWc6jm3MvQDTogQkiqIhJV0nBQBTU+3okKCFDy9WwferkHjtxib7t3xIUQtHxnIwtx4mpg26/HfwVNVDb4oI9RHmx5WGelRVlrtiw43zboCLaxv46AZeB3IlTkwouebTr1y2NjSpHz68WNFjHvupy3q8TFn3Hos2IAk4Ju5dCo8B3wP7VPr/FGaKiG+T+v+TQqIrOqMTL1VdWV1DdmcbO8KXBz6esmYWYKPwDL5b5FA1a0hwapHiom0r/cKaoqr+27/XcrS5UwSMbQAAAABJRU5ErkJggg==)](https://deepwiki.com/weaponsforge/ph-regions)
<!-- DeepWiki badge generated by https://deepwiki.ryoppippi.com/ -->

### Online Demo

- REST API: <https://ph-regions.vercel.app/api>
- API documentation
- Static: <https://ph-regions.vercel.app>
- Interactive: <https://ph-regions.vercel.app/docs>

<br>

<div align="center">
Expand All @@ -18,18 +25,19 @@ A RESTful API that serves **hierarchical location data** of the Philippines —
</div>
<br>

### Online Deployments
### Local Development Screenshots

- REST API: <https://ph-regions.vercel.app/api>
- API documentation
- Static: <https://ph-regions.vercel.app>
- Interactive: <https://ph-regions.vercel.app/docs>
<p align="center">
<img src="assets/ph_regions_ss_01.png" width="45%" loading="lazy" alt="Static API docs screenshot" />
<img src="assets/ph_regions_ss_02.png" width="45%" loading="lazy" alt="Interactive API docs screenshot" />
</p>

### Table of Contents

- [Requirements](#-requirements)
- [Core Libraries/Frameworks](#-core-librariesframeworks)
- [Project Folder Structure](#-project-folder-structure)
- [Quickstart](#-quickstart)
- [Installation](#️-installation)
- [Usage](#-usage)
- [Using Docker](#-using-docker)
Expand Down Expand Up @@ -63,9 +71,9 @@ We welcome contributions! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for gu
| tsx | `4.20.3` | Executes TypeScript and TSX files directly, ideal for dev and script running. |
| tsc-alias | `1.8.16` | Rewrites path aliases in compiled TypeScript output (`tsconfig` paths). |
| ESlint | `9.32.0` | Linting tool that enforces code style, quality, and formatting rules. |
| @asteasolutions/zod-to-openapi | `8.1.0` | Generates an OpenAPI yaml file from Zod schemas. |
| @redocly/cli | `2.1.0` | Generates an API documentation using an OpenAPI yaml input. |
| swagger-ui-express | `4.1.8` | Generates a Swagger UI API documentation using an OpenAPI json input. |
| @asteasolutions/zod-to-openapi | `8.1.0` | Generates OpenAPI YAML and JSON files from Zod schemas. |
| @redocly/cli | `2.1.0` | Generates an API documentation using an OpenAPI YAML input. |
| swagger-ui-express | `4.1.8` | Generates a Swagger UI API documentation using an OpenAPI JSON input. |

</details>
<br>
Expand All @@ -90,6 +98,25 @@ The main app is inside the `📂 server/src` folder.

<br>

## 🆕 Quickstart

Follow these steps to set up and use the code repository easily. Read the [Installation](#️-installation) section for detailed setup and usage instructions.

1. Create a `.env` file in the `/server` directory, copying the contents of the `.env.example` file.

2. Build the development images.<br>
`docker compose build`

3. Run the development containers.<br>
`docker compose up`

4. Create initial data.<br>
`docker exec -it weaponsforge-ph-regions npm run seed`

5. Access the available resources:
- REST API documentation: http://localhost:3001
- REST API endpoints: http://localhost:3001/api

## 🛠️ Installation

1. Clone the repository.<br>
Expand Down Expand Up @@ -121,8 +148,8 @@ The main app is inside the `📂 server/src` folder.

4. Seed (create) the initial data set.<br>
- This step requires running the `"npm run seed"` script.
- Proceed to the [**"Using Docker"**](#-using-docker) section for more information on running the app using Docker.
- Run the command after successfully running the server app from **Usage - Using Docker - step # 3**.
- Proceed to the [**"Using Docker"**](#-using-docker) section for more information on running the app first using Docker.
- Run the command after successfully running the server app using Docker from [A. Use Pre-Built Development Docker Image](#a-use-pre-built-development-docker-image) or [B. Build the Development Docker Image](#b-build-the-development-docker-image).
```sh
docker exec -it weaponsforge-ph-regions npm run seed
```
Expand Down Expand Up @@ -285,7 +312,7 @@ Runs the database seeder script, inserting initial data contents to the database

Generates the OpenAPI `openapi.yaml` (YAML) and `openapi.json` (JSON) files into the `/server/public` directory.

> 💡 **NOTE:** Comment out **Line #20, [public folder volume]** in the `docker-compose.yml` file to update the `"/server/public/openapi.yaml"` and `"/server/public/openapi.json"` files in the host volume.
> 💡 **NOTE:** Comment out **Line #21, under [public folder volume]** in the `docker-compose.yml` file to update the `"/server/public/openapi.yaml"` and `"/server/public/openapi.json"` files in the host volume.

### `npm run docs:build`

Expand All @@ -295,13 +322,13 @@ Builds the API documentation using the [Redocly CLI](https://www.npmjs.com/packa

Standard NPM build script that runs transpile, builds OpenAPI docs, and copies Swagger UI assets (`transpile` + `docs:build` + `docs:swagger`).

> 💡 **NOTE:** Comment out **Line #20 under [public folder volume]** in the `docker-compose.yml` file when running this script via Docker to resolve `EACCES: permission denied` errors.
> 💡 **NOTE:** Comment out **Line #21 under [public folder volume]** in the `docker-compose.yml` file when running this script via Docker to resolve `EACCES: permission denied` errors.

### `npm run docs:swagger`

Copies the minimal Swagger UI assets (CSS/JS) from `node_modules` into `/public/docs`. The page `public/docs/index.html` references these assets and the generated OpenAPI spec in `/public/openapi.json`

> 💡 **NOTE:** Comment out **Line #20, [public folder volume]** in the `docker-compose.yml` file when running this script via Docker to resolve `EACCES: permission denied` errors.
> 💡 **NOTE:** Comment out **Line #21, under [public folder volume]** in the `docker-compose.yml` file when running this script via Docker to resolve `EACCES: permission denied` errors.

</details>
<br>
Expand Down Expand Up @@ -348,17 +375,18 @@ Follow the steps for adding (or editing) new endpoints to the API.
<details>
<summary>👉 Click to view the guidelines</summary>

1. **Create a Zod schema**<br>
Follow the patterns in the `📐 schemas` directory (e.g., `province.schema.ts`).

2. **Create a Mongoose model**<br>
Follow the patterns in the `🧊 models` directory (e.g., `province.model.ts`).
1. **Create a Zod schema**
- Follow the patterns in the `📐 schemas` directory (e.g., `province.schema.ts`).
- Ensure each schema field has a Zod `.meta()` attached, with a `description` key containing a short description of the field, and an `example`.
2. **Create a Mongoose model**
- Follow the patterns in the `🧊 models` directory (e.g., `province.model.ts`).
- The Zod-inferred type (`z.infer()`) of the **Zod Schema** created in **step # 1** should be used to type-cast this model's **Mongoose Schema**.

3. **Set up routes (API endpoints)**<br>
Add new routes for the model in the `🪧 routes` directory (e.g., `/routes/province.ts`) **without input validation** for now.

4. **Define query, response, and request schemas**<br>
Create Zod schemas for query, response, params, and body in:<br>
Create Zod schemas for HTTP query, response, params, and body in:<br>
`server/src/scripts/openapi/docs/api.schema.ts`

> 💡 **INFO**<br>
Expand Down
11 changes: 11 additions & 0 deletions assets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## assets

This folder contains media assets used within the repository.

### Notes

- The `architecture.drawio` file was created using [draw.io](https://www.drawio.com/) v28.1.2.
> Export `assets/architecture.drawio` to `assets/architecture.png` (**File** → **Export as** → **PNG**) whenever the diagram changes.

@weaponsforge<br>
20250922
16 changes: 14 additions & 2 deletions assets/architecture.drawio
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<mxCell id="7-nY-5UTIFV4o-A8x8mZ-66" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="7-nY-5UTIFV4o-A8x8mZ-56" target="7-nY-5UTIFV4o-A8x8mZ-65" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="JXwXZkAHh5WOhnee5du0-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;dashed=1;" edge="1" parent="1" source="7-nY-5UTIFV4o-A8x8mZ-56" target="JXwXZkAHh5WOhnee5du0-1">
<mxCell id="JXwXZkAHh5WOhnee5du0-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;dashed=1;" parent="1" source="7-nY-5UTIFV4o-A8x8mZ-56" target="JXwXZkAHh5WOhnee5du0-1" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="7-nY-5UTIFV4o-A8x8mZ-56" value="middleware&lt;div&gt;(validation)&lt;/div&gt;" style="verticalLabelPosition=top;outlineConnect=0;align=center;dashed=0;html=1;verticalAlign=bottom;shape=mxgraph.pid.misc.filter_2;labelPosition=center;spacingTop=0;spacingBottom=5;" parent="1" vertex="1">
Expand Down Expand Up @@ -48,9 +48,21 @@
<mxCell id="7-nY-5UTIFV4o-A8x8mZ-81" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.445;entryY=0.939;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="7-nY-5UTIFV4o-A8x8mZ-65" target="7-nY-5UTIFV4o-A8x8mZ-48" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="JXwXZkAHh5WOhnee5du0-1" value="schema&lt;div&gt;(Zod)&lt;/div&gt;" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;fillColor=#505050;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.concepts.sign_up;" vertex="1" parent="1">
<mxCell id="JXwXZkAHh5WOhnee5du0-1" value="schema&lt;div&gt;(Zod)&lt;/div&gt;" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;fillColor=#505050;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.concepts.sign_up;" parent="1" vertex="1">
<mxGeometry x="-350" y="88.55" width="51" height="47" as="geometry" />
</mxCell>
<mxCell id="xfzBbhjO1vl4Opf90gaK-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="xfzBbhjO1vl4Opf90gaK-2" target="7-nY-5UTIFV4o-A8x8mZ-27">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="xfzBbhjO1vl4Opf90gaK-2" value="MongoDB&lt;div&gt;seed script&lt;/div&gt;" style="sketch=0;aspect=fixed;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;align=center;fillColor=#00188D;shape=mxgraph.azure.script_file" vertex="1" parent="1">
<mxGeometry x="-592" y="262.5" width="47" height="50" as="geometry" />
</mxCell>
<mxCell id="xfzBbhjO1vl4Opf90gaK-4" value="Developer" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" vertex="1" parent="1">
<mxGeometry x="-780" y="290" width="30" height="60" as="geometry" />
</mxCell>
<mxCell id="xfzBbhjO1vl4Opf90gaK-5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;dashed=1;" edge="1" parent="1" source="xfzBbhjO1vl4Opf90gaK-4" target="xfzBbhjO1vl4Opf90gaK-2">
<mxGeometry relative="1" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
Expand Down
Binary file modified assets/architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/ph_regions_ss_01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/ph_regions_ss_02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ph-regions",
"version": "1.1.0",
"version": "1.1.1",
"type": "module",
"description": "A RESTful API that serves hierarchical location data of the Philippines — including regions, provinces, municipalities, and a randomly generated number of barangays per municipality.",
"main": "dist/server.js",
Expand Down