Skip to content

Commit

Permalink
Added postal area update route api
Browse files Browse the repository at this point in the history
  • Loading branch information
antoineludeau committed Dec 13, 2024
1 parent e885222 commit 3c64643
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use strict'

const {POSTGRES_BAN_USER} = process.env

/** @type {import('sequelize-cli').Migration} */
module.exports = {
async up(queryInterface) {
await queryInterface.sequelize.query(`GRANT USAGE, SELECT, UPDATE ON SEQUENCE external.postal_area_id_seq TO "${POSTGRES_BAN_USER}";`)
},

async down(queryInterface) {
await queryInterface.sequelize.query(`REVOKE USAGE, SELECT, UPDATE ON SEQUENCE external.postal_area_id_seq FROM "${POSTGRES_BAN_USER}";`)
}
}
44 changes: 44 additions & 0 deletions lib/api/postal-area/models.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {PostalArea, sequelize} from '../../util/sequelize.js'

export const replacePostalAreasPerDistrictCog = async (cog, postalAreas) => {
const formattedPostalAreas = postalAreas.map(({postalCode, geometry}) => ({
inseeCom: cog,
postalCode,
geometry: JSON.stringify(geometry),
}))

const transaction = await sequelize.transaction()

try {
const postalAreasDeletedCount = await PostalArea.destroy(
{
where: {inseeCom: cog},
transaction,
}
)

const insertQuery = `
INSERT INTO external.postal_area ("postalCode", "inseeCom", geometry, "createdAt", "updatedAt")
VALUES ($1, $2, ST_SetSRID(ST_GeomFromGeoJSON($3), 2154), NOW(), NOW())
`

const insertPromises = formattedPostalAreas.map(async ({postalCode, inseeCom, geometry}) => {
const result = await sequelize.query(insertQuery, {
bind: [postalCode, inseeCom, geometry],
transaction,
})
if (result[1] !== 1) {
throw new Error(`Failed to insert postal area with postalCode: ${postalCode}`)
}
})

await Promise.all(insertPromises)

await transaction.commit()

return {postalAreasCreatedCount: formattedPostalAreas.length, postalAreasDeletedCount}
} catch (error) {
await transaction.rollback()
throw error
}
}
37 changes: 37 additions & 0 deletions lib/api/postal-area/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import 'dotenv/config.js' // eslint-disable-line import/no-unassigned-import
import express from 'express'
import auth from '../../middleware/auth.js'
import {handleAPIResponse} from '../helper.js'
import {replacePostalAreasPerDistrictCog} from './models.js'

const app = new express.Router()
app.use(express.json())

app.put('/district/cog/:cog', auth, async (req, res) => {
try {
const {cog} = req.params
const postalAreas = req.body

if (!cog) {
handleAPIResponse(res, 400, 'COG code is required', {})
return
}

if (!Array.isArray(postalAreas) || postalAreas.length === 0) {
handleAPIResponse(res, 400, 'An array of items is required', {})
return
}

const {postalAreasCreatedCount, postalAreasDeletedCount} = await replacePostalAreasPerDistrictCog(cog, postalAreas)

handleAPIResponse(res, 200, 'Postal areas updated', {
createdCount: postalAreasCreatedCount,
deletedCount: postalAreasDeletedCount,
})
} catch (error) {
console.error(error)
handleAPIResponse(res, 500, 'Internal server error', {})
}
})

export default app
2 changes: 2 additions & 0 deletions lib/api/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import statusRoutes from './job-status/routes.js'
import banIdRoutes from './ban-id/routes.js'
import certificatRoutes from './certificate/routes.js'
import postalDatanovaRoutes from './postal-datanova/routes.js'
import postalAreaRoutes from './postal-area/routes.js'
import exportToExploitationDBRoutes from './export-to-exploitation-db/routes.js'

const app = new express.Router()
Expand All @@ -19,6 +20,7 @@ app.use('/job-status', statusRoutes)
app.use('/ban-id', banIdRoutes)
app.use('/certificate', certificatRoutes)
app.use('/postal-datanova', postalDatanovaRoutes)
app.use('/postal-area', postalAreaRoutes)
app.use('/export-to-exploitation-db', exportToExploitationDBRoutes)

export default app
25 changes: 25 additions & 0 deletions lib/util/sequelize.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,31 @@ export const Datanova = sequelize.define('Datanova', {
timestamps: true,
})

export const PostalArea = sequelize.define('PostalArea', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
postalCode: {
type: DataTypes.STRING,
allowNull: false,
},
inseeCom: {
type: DataTypes.STRING,
allowNull: false,
},
geometry: {
type: DataTypes.GEOMETRY,
allowNull: false,
},
}, {
schema: 'external',
tableName: 'postal_area',
timestamps: true,
})

export const init = async () => {
try {
await sequelize.authenticate()
Expand Down

0 comments on commit 3c64643

Please sign in to comment.