Skip to content

Commit 2ffaaf7

Browse files
feat: update data to v4 (#520)
BREAKING CHANGES
1 parent 023d3af commit 2ffaaf7

File tree

70 files changed

+4717
-2068
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+4717
-2068
lines changed

docs/upgrading/upgrade-to-v7.md

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
# Upgrade to idn-area version 7
2+
3+
## Breaking Changes Overview
4+
5+
Version 7 introduces significant changes to the code format and data structure. This upgrade uses [idn-area-data v4.0.0](https://github.com/fityannugroho/idn-area-data/releases/tag/v4.0.0) which includes data changes and formats. We also restores the original dotted notation for area codes that was previously stripped in earlier API versions.
6+
7+
## Requirements
8+
9+
### Node.js Version Requirement
10+
11+
Version 7 requires **Node.js ≥22.0.0** due to the updated `idn-area-data` dependency.
12+
13+
```json
14+
{
15+
"engines": {
16+
"node": ">=22.0.0"
17+
}
18+
}
19+
```
20+
21+
### Data Version Update
22+
23+
This version uses **idn-area-data v4.0.0** and introduces the following changes:
24+
25+
#### Format Changes
26+
- **Restored original dotted notation**: The API now preserves the dotted format from the source data instead of removing dots like in previous versions
27+
- **Standardized name capitalization**: Changed from ALL CAPS to proper case formatting
28+
29+
#### Data Updates
30+
- Latest 2025 administrative area data
31+
- Improved data structure consistency
32+
- Enhanced data validation
33+
34+
#### Technical Background
35+
The underlying `idn-area-data` package has always used dotted notation in its source data (e.g., regency codes like `32.01`, district codes like `32.01.01`). However, previous API versions processed this data and removed the dots before serving it. Version 7 eliminates this processing step and serves the data in its original format, making the hierarchical relationships more explicit and easier to understand.
36+
37+
## Backward Compatibility
38+
39+
⚠️ **This is a breaking change.** Version 7 is **NOT** backward compatible with v6 due to the fundamental change in code formats.
40+
41+
## Restored Dotted Notation for Area Codes
42+
43+
**Important Context**: The underlying data source (`idn-area-data`) has always used dotted notation (e.g., `32.01`, `32.01.01`), but previous API versions (including v6) removed the dots to provide numeric-only codes. **Version 7 now preserves the original dotted format** from the data source.
44+
45+
### Code Format Changes
46+
47+
| Administrative Level | v6 Format | v7 Format |
48+
| -------------------- | ------------ | --------------- |
49+
| Province | `32` | `32` |
50+
| Regency | `3201` | `32.01` |
51+
| District | `320101` | `32.01.01` |
52+
| Village | `3201012001` | `32.01.01.2001` |
53+
| Island | `320140001` | `32.01.40001` |
54+
55+
### Background: Why This Change?
56+
57+
In previous versions (v6 and earlier), the API processed the source data and **removed dots** to provide numeric-only codes. For example:
58+
- Source data: `32.01` (Kabupaten Bogor)
59+
- API v6 output: `3201` (dots removed)
60+
- API v7 output: `32.01` (preserves original format)
61+
62+
This change aligns the API output with the actual data structure used in the Indonesian administrative system and makes the hierarchical relationship more explicit.
63+
64+
### Database Schema Updates
65+
66+
The following field lengths have been updated to accommodate the new dotted format:
67+
68+
| Table | Field | v6 Length | v7 Length |
69+
| ----------- | --------------- | ----------- | ----------- |
70+
| `regencies` | `code` | VARCHAR(4) | VARCHAR(5) |
71+
| `districts` | `code` | VARCHAR(6) | VARCHAR(8) |
72+
| `districts` | `regency_code` | VARCHAR(4) | VARCHAR(5) |
73+
| `villages` | `code` | VARCHAR(10) | VARCHAR(13) |
74+
| `villages` | `district_code` | VARCHAR(6) | VARCHAR(8) |
75+
| `islands` | `code` | VARCHAR(9) | VARCHAR(11) |
76+
| `islands` | `regency_code` | VARCHAR(4) | VARCHAR(5) |
77+
78+
## Updated Name Capitalization
79+
80+
Version 7 also standardizes the capitalization of administrative area names to follow proper name formatting instead of ALL CAPS.
81+
82+
### Name Format Changes
83+
84+
| Administrative Level | v6 Format (ALL CAPS) | v7 Format (Proper Case) |
85+
| -------------------- | -------------------- | ---------------------------- |
86+
| Province | `JAWA BARAT` | `Jawa Barat` |
87+
| Province | `DI YOGYAKARTA` | `Daerah Istimewa Yogyakarta` |
88+
| Regency | `KABUPATEN BOGOR` | `Kabupaten Bogor` |
89+
| Regency | `KOTA BOGOR` | `Kota Bogor` |
90+
| District | `NANGGUNG` | `Nanggung` |
91+
| Village | `BANTARJATI` | `Bantarjati` |
92+
| Island | `PULAU RAMBUT` | `Pulau Rambut` |
93+
94+
### Examples of Name Changes
95+
96+
**Provinces:**
97+
- `ACEH``Aceh`
98+
- `SUMATERA UTARA``Sumatera Utara`
99+
- `JAWA BARAT``Jawa Barat`
100+
- `DI YOGYAKARTA``Daerah Istimewa Yogyakarta`
101+
102+
**Regencies:**
103+
- `KABUPATEN ACEH SELATAN``Kabupaten Aceh Selatan`
104+
- `KABUPATEN BOGOR``Kabupaten Bogor`
105+
- `KOTA JAKARTA PUSAT``Kota Jakarta Pusat`
106+
107+
## API Response Changes
108+
109+
### Updated Response Examples
110+
111+
All endpoints now return codes in the new dotted format:
112+
113+
**Get a regency (v7):**
114+
```
115+
GET /regencies/32.01
116+
```
117+
```json
118+
{
119+
"statusCode": 200,
120+
"message": "OK",
121+
"data": {
122+
"code": "32.01",
123+
"name": "Kabupaten Bogor",
124+
"provinceCode": "32"
125+
}
126+
}
127+
```
128+
129+
**Get districts (v7):**
130+
```
131+
GET /districts?regencyCode=32.01
132+
```
133+
```json
134+
{
135+
"statusCode": 200,
136+
"message": "OK",
137+
"data": [
138+
{
139+
"code": "32.01.01",
140+
"name": "Nanggung",
141+
"regencyCode": "32.01"
142+
},
143+
{
144+
"code": "32.01.02",
145+
"name": "Leuwiliang",
146+
"regencyCode": "32.01"
147+
}
148+
],
149+
"meta": {
150+
"total": 2,
151+
"pages": {
152+
"first": 1,
153+
"last": 1,
154+
"current": 1,
155+
"previous": null,
156+
"next": null
157+
}
158+
}
159+
}
160+
```
161+
162+
### Island Response Improvements
163+
164+
Islands now automatically include calculated decimal coordinates in the response:
165+
166+
```json
167+
{
168+
"code": "32.01.40001",
169+
"name": "Pulau Rambut",
170+
"coordinate": "06°10'30.00\" S 106°38'30.00\" E",
171+
"isOutermostSmall": false,
172+
"isPopulated": false,
173+
"regencyCode": "32.01",
174+
"latitude": -6.175000000000001,
175+
"longitude": 106.64166666666668
176+
}
177+
```
178+
179+
The `latitude` and `longitude` fields are now automatically computed from the `coordinate` field and included in all island responses.
180+
181+
## New Features
182+
183+
### Enhanced Island Data
184+
185+
Islands now include automatically calculated decimal coordinates:
186+
- `latitude`: Decimal latitude from DMS coordinate
187+
- `longitude`: Decimal longitude from DMS coordinate
188+
189+
These fields are computed server-side and always included in island responses.
190+
191+
### Improved Testing Infrastructure
192+
193+
Version 7 includes significant improvements to the testing framework:
194+
- Comprehensive E2E testing covering complete user journeys
195+
- Simplified test data fixtures
196+
- Better mock services for unit testing
197+
- Performance-focused testing strategies
198+
199+
## FAQ
200+
201+
### Q: Can I gradually migrate to v7?
202+
**A:** No, due to the fundamental change in code format, you need to migrate completely. The old numeric format is no longer supported.
203+
204+
### Q: Are there any tools to help with migration?
205+
**A:** You can create migration scripts using the patterns shown above. Consider writing automated tests to verify your migration.
206+
207+
### Q: Will the API endpoints change?
208+
**A:** No, the endpoint URLs remain the same. Only the code formats in requests and responses have changed.
209+
210+
## Need Help?
211+
212+
If you encounter issues during migration:
213+
1. Check the [main documentation](../../README.md) for usage examples
214+
2. Review the [test fixtures](../../test/fixtures/data.fixtures.ts) for correct code formats
215+
3. Open an issue on [GitHub](https://github.com/fityannugroho/idn-area/issues)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"@types/supertest": "^6.0.3",
6767
"@vitest/coverage-v8": "^3.2.4",
6868
"husky": "^9.1.7",
69-
"idn-area-data": "^3.1.2",
69+
"idn-area-data": "^4.0.0",
7070
"lint-staged": "^16.1.5",
7171
"prisma": "^6.14.0",
7272
"source-map-support": "^0.5.21",

pnpm-lock.yaml

Lines changed: 10 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
Warnings:
3+
4+
- The primary key for the `districts` table will be changed. If it partially fails, the table could be left without primary key constraint.
5+
- The primary key for the `islands` table will be changed. If it partially fails, the table could be left without primary key constraint.
6+
- The primary key for the `regencies` table will be changed. If it partially fails, the table could be left without primary key constraint.
7+
- The primary key for the `villages` table will be changed. If it partially fails, the table could be left without primary key constraint.
8+
9+
*/
10+
-- DropForeignKey
11+
ALTER TABLE `districts` DROP FOREIGN KEY `districts_regency_code_fkey`;
12+
13+
-- DropForeignKey
14+
ALTER TABLE `islands` DROP FOREIGN KEY `islands_regency_code_fkey`;
15+
16+
-- DropForeignKey
17+
ALTER TABLE `villages` DROP FOREIGN KEY `villages_district_code_fkey`;
18+
19+
-- DropIndex
20+
DROP INDEX `districts_regency_code_fkey` ON `districts`;
21+
22+
-- DropIndex
23+
DROP INDEX `islands_regency_code_fkey` ON `islands`;
24+
25+
-- DropIndex
26+
DROP INDEX `villages_district_code_fkey` ON `villages`;
27+
28+
-- AlterTable
29+
ALTER TABLE `districts` DROP PRIMARY KEY,
30+
MODIFY `code` VARCHAR(8) NOT NULL,
31+
MODIFY `regency_code` VARCHAR(5) NOT NULL,
32+
ADD PRIMARY KEY (`code`);
33+
34+
-- AlterTable
35+
ALTER TABLE `islands` DROP PRIMARY KEY,
36+
MODIFY `code` VARCHAR(11) NOT NULL,
37+
MODIFY `regency_code` VARCHAR(5) NULL,
38+
ADD PRIMARY KEY (`code`);
39+
40+
-- AlterTable
41+
ALTER TABLE `regencies` DROP PRIMARY KEY,
42+
MODIFY `code` VARCHAR(5) NOT NULL,
43+
ADD PRIMARY KEY (`code`);
44+
45+
-- AlterTable
46+
ALTER TABLE `villages` DROP PRIMARY KEY,
47+
MODIFY `code` VARCHAR(13) NOT NULL,
48+
MODIFY `district_code` VARCHAR(8) NOT NULL,
49+
ADD PRIMARY KEY (`code`);
50+
51+
-- AddForeignKey
52+
ALTER TABLE `districts` ADD CONSTRAINT `districts_regency_code_fkey` FOREIGN KEY (`regency_code`) REFERENCES `regencies`(`code`) ON DELETE RESTRICT ON UPDATE CASCADE;
53+
54+
-- AddForeignKey
55+
ALTER TABLE `islands` ADD CONSTRAINT `islands_regency_code_fkey` FOREIGN KEY (`regency_code`) REFERENCES `regencies`(`code`) ON DELETE SET NULL ON UPDATE CASCADE;
56+
57+
-- AddForeignKey
58+
ALTER TABLE `villages` ADD CONSTRAINT `villages_district_code_fkey` FOREIGN KEY (`district_code`) REFERENCES `districts`(`code`) ON DELETE RESTRICT ON UPDATE CASCADE;

prisma/mysql/schema.prisma

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,22 @@ generator client {
99
}
1010

1111
model District {
12-
code String @id @db.VarChar(6)
12+
code String @id @db.VarChar(8)
1313
name String @db.VarChar(255)
14-
regencyCode String @map("regency_code") @db.VarChar(4)
14+
regencyCode String @map("regency_code") @db.VarChar(5)
1515
regency Regency @relation(fields: [regencyCode], references: [code])
1616
villages Village[]
1717
1818
@@map("districts")
1919
}
2020

2121
model Island {
22-
code String @id @db.VarChar(9)
22+
code String @id @db.VarChar(11)
2323
coordinate String @db.VarChar(30)
2424
isOutermostSmall Boolean @map("is_outermost_small")
2525
isPopulated Boolean @map("is_populated")
2626
name String @db.VarChar(255)
27-
regencyCode String? @map("regency_code") @db.VarChar(4)
27+
regencyCode String? @map("regency_code") @db.VarChar(5)
2828
regency Regency? @relation(fields: [regencyCode], references: [code])
2929
3030
@@map("islands")
@@ -39,7 +39,7 @@ model Province {
3939
}
4040

4141
model Regency {
42-
code String @id @db.VarChar(4)
42+
code String @id @db.VarChar(5)
4343
name String @db.VarChar(255)
4444
provinceCode String @map("province_code") @db.VarChar(2)
4545
islands Island[]
@@ -58,8 +58,8 @@ model SeederLogs {
5858
}
5959

6060
model Village {
61-
code String @id @db.VarChar(10)
62-
districtCode String @map("district_code") @db.VarChar(6)
61+
code String @id @db.VarChar(13)
62+
districtCode String @map("district_code") @db.VarChar(8)
6363
name String @db.VarChar(255)
6464
district District @relation(fields: [districtCode], references: [code])
6565

0 commit comments

Comments
 (0)