Skip to content

Save maps to database#116

Open
categulario wants to merge 24 commits intohotosm:developfrom
categulario:feat/map-saving
Open

Save maps to database#116
categulario wants to merge 24 commits intohotosm:developfrom
categulario:feat/map-saving

Conversation

@categulario
Copy link
Collaborator

@categulario categulario commented Mar 8, 2026

A few things happen here. All surrounding the idea of saving a map.

  • a migration that removes the uniqueness of the user_id from maps table is created.
  • pydantic schemas are separated from models for clarity.
  • two endpoints are created (GET /map and POST /map) and an old one is renamed (GET /map/new). The rename allows for a more restful interface.
  • deprecated dependency react-router-dom is replaced by react-router.
  • two icons are added.
  • SaveButton is renamed DownloadButton and a new SaveButton is created.
  • translations for new messages are added.
  • the Header component is refactored to receive buttons as children, thus simplifying its logic a lot.
  • a MapList page is created containing the table of maps that the user has created.

@categulario categulario requested a review from emi420 March 8, 2026 06:35
@emi420
Copy link
Contributor

emi420 commented Mar 8, 2026

@categulario I see that there are unfinished things here, because it's WIP, let's finish all features before creating the PR to develop.

You can also cherry pick some finished changes and create a PR with that if you want, like changes in the router dependency or in the database/models, as long as the existing functionality keeps working.

@categulario categulario changed the title WIP: Save maps do database Save maps do database Mar 10, 2026
@categulario categulario marked this pull request as ready for review March 10, 2026 03:54
@categulario categulario changed the title Save maps do database Save maps to database Mar 10, 2026
Copy link
Contributor

@emi420 emi420 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work @categulario !! There are just a few things to be fixed before approving the PR.

  • Live compatibility with new code. This feature is now broken because the map can't be created after changes on endpoints.
  • Bug with tags
  • Track media files ownership
  • Small naming issue and missing translation

} else if (message.file.endsWith("mp4")) {
content = <video controls className="popupVideo" alt={message.file} src={message.file} />
} else if (message.file.endsWith("jpg")) {
} else if (message.file.endsWith("opus")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! this is for the Live version and needs to be solved ASAP :)

</div>

{ loading ? <>
Uploading media...
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This text needs translation, could you add FormattedMessage please?



@api_router.post("/map")
async def create_chatmap(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are using "map" everywhere, should we use "map" instead of "chatmap"?

create_map
delete_map
...


# User's Private Map Data Endpoint
@api_router.get("/map", response_model=FeatureCollection)
@api_router.get("/map/new", response_model=FeatureCollection)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This endpoint is currently being used for getting the only map available for the user: the Live map, which is created when linking a device using a QR code and then updated by data.process_chat_entries.

We should take this into account, maybe by doing a Post to /map/new when linking the device and having column for identifying the map as a "Live" map linked to a device.

When testing this branch and linking a device the process is failing

INFO:     172.19.0.1:63570 - "GET /v1/map/new HTTP/1.1" 401 Unauthorized

} for map, count in maps]


@api_router.post("/map/media")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should keep tracking of which file belongs to which map, like we do in uMap, so we can then remove media files when removing a map. Would make sense to add a UploadedFiles table?

We can also take advantage of this for blocking access to files when the map is private.

This is what we have in uMap:

Image

return {"map_id": map_id, "sharing": map_obj.sharing.value}


@api_router.get("/media/{filename}", response_class=StreamingResponse)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once we add the relation between files and maps, we should add access control to these files. Media files will be available only if the map is public of logged user is owner of the map. Another way to do this is to add ownership to each file.

const tags = data.features.reduce((accumulator, currentValue) => {
if (currentValue.properties.tags) {
currentValue.properties.tags.forEach(tag => {
currentValue.properties.tags.split(",").forEach(tag => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's bug here, I see this error when trying to add tags:

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants