Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
462afae
fix(AI): add null check to model name (#645)
hestela Apr 17, 2026
10ba800
fix(AI): qwen2.5 loading on every chat message (#649)
hestela Apr 17, 2026
10e8957
fix: prevent ZIM corrupt file crash and deduplicate Ollama download l…
jakeaturner Apr 17, 2026
b365130
fix(disk-collector): fix storage reporting for NFS mounts
bgauger Apr 9, 2026
898c444
fix(disk-display): show NAS Storage label in fsSize fallback path
bgauger Apr 9, 2026
b5d4804
fix(downloads): stage downloads to .tmp to prevent Kiwix loading part…
artbird309 Mar 21, 2026
f1dd184
fix(Downloads): remove duplicate err listnr and improv Range req stab…
jakeaturner Apr 17, 2026
0d5b6f7
fix(security): SSRF validation for map downloads and error sanitizati…
LuisMIguelFurlanettoSousa Apr 17, 2026
53d143b
fix(AI): allow cancelling in-progress model downloads and ensure cons…
chriscrosstalk Apr 17, 2026
d8ee6f5
build(deps): bump follow-redirects from 1.15.11 to 1.16.0 in /admin (…
dependabot[bot] Apr 17, 2026
2075a62
build(deps): bump axios from 1.13.5 to 1.15.0 in /admin (#708)
dependabot[bot] Apr 17, 2026
5ee4e11
build(deps): bump protocol-buffers-schema from 3.6.0 to 3.6.1 in /adm…
dependabot[bot] Apr 17, 2026
38dfb19
build(deps): bump protobufjs from 7.5.4 to 7.5.5 in /admin (#737)
dependabot[bot] Apr 17, 2026
1aa2601
build(deps): bump @adonisjs/http-server from 7.8.0 to 7.8.1 in /admin…
dependabot[bot] Apr 17, 2026
4497e36
build(deps-dev): bump vite from 6.4.1 to 6.4.2 in /admin (#677)
dependabot[bot] Apr 17, 2026
dcd9f4b
build(deps): bump lodash from 4.17.23 to 4.18.1 in /admin (#643)
dependabot[bot] Apr 17, 2026
6e4795f
docs: update release notes
jakeaturner Apr 17, 2026
c4aa23a
docs: add Community Add-Ons page with field manuals + W3Schools packs…
chriscrosstalk Apr 20, 2026
776d099
fix(qdrant): disable anonymous telemetry by default (#747)
chriscrosstalk Apr 20, 2026
644170e
fix(UI): gate NAS Storage label on network filesystem type (#749)
bgauger Apr 20, 2026
36b7613
fix(AI): stop local nomad_ollama container when remote Ollama is conf…
chriscrosstalk Apr 20, 2026
d22c0b2
fix(ZIM): accumulate across Kiwix pages to prevent empty Content Expl…
chriscrosstalk Apr 20, 2026
9c98d82
fix(rag): repair ZIM embedding pipeline (sync filter, batch gate, DOM…
chriscrosstalk Apr 20, 2026
08d1447
build: write version.json from VERSION build-arg (#754)
chriscrosstalk Apr 21, 2026
90946ec
docs: require linked issue for non-trivial PRs (#799)
chriscrosstalk Apr 28, 2026
b168001
fix(install): warn loudly on non-x86_64 architectures before pulling …
chriscrosstalk Apr 28, 2026
3bacd14
feat(content-manager): add sortable file size column (#698)
chriscrosstalk Apr 28, 2026
00b4b26
fix(API): skip compression for Server-Sent Events (#798)
chriscrosstalk Apr 28, 2026
b194dfa
fix(RAG): pass num_ctx and truncate to Ollama embed call (#763)
chriscrosstalk Apr 28, 2026
269c7ce
fix(API): accept notes, marker_type, and position on markers endpoint…
jrsphoto Apr 28, 2026
fe57d59
docs: add map markers to API reference (#783)
kennethbrewer3 Apr 28, 2026
cc789c1
fix(RAG): add start button in kb modal and ensure restart policy exis…
hestela Apr 28, 2026
322087c
fix(UI): improve global map banner display logic (#702)
Gujiassh Apr 29, 2026
5924056
feat(AI): improved AMD GPU acceleration for Ollama via ROCm + HSA ove…
chriscrosstalk Apr 29, 2026
0836d84
docs: added notes field info to the map pin API reference (#803)
kennethbrewer3 Apr 29, 2026
bb1834a
fix(UI): wire map file delete confirmation to API (#732)
cuyua9 May 3, 2026
360e7a0
feat(content-updates): show size, surface downloads in Active Downloads
chriscrosstalk Apr 22, 2026
27cd803
feat(Maps): regional map downloads via go-pmtiles extract (#780)
bgauger May 3, 2026
822b946
fix(UI): Country Picker UX polish + auto-refresh stored files (#817)
chriscrosstalk May 3, 2026
a2f3a84
feat(maps): show map coordinates on mouse move (#786)
kennethbrewer3 May 3, 2026
8ef2c69
docs: link to new WSL2 install guide from README and FAQ
chriscrosstalk Apr 29, 2026
d81b66b
chore(deps): pin all deps to exact versions
jakeaturner May 4, 2026
d66eaa3
build(deps): bump picomatch in /admin
dependabot[bot] Mar 25, 2026
a7dbee5
feat(Content): custom ZIM library sources with pre-seeded mirrors (#593)
chriscrosstalk May 4, 2026
0ddcfe9
fix(System): self-heal stale updateAvailable flag after sidecar-drive…
jakeaturner May 4, 2026
0fdf31c
docs: update release notes
jakeaturner May 4, 2026
1ad898b
fix(UI): four fixes for the System Update page (#827)
chriscrosstalk May 5, 2026
cb47e1e
chore(release): 1.32.0-rc.1 [skip ci]
cosmistack-bot May 4, 2026
03ab614
fix(Maps): send filename instead of full path to delete endpoint
bgauger May 4, 2026
6328256
fix(Maps): render notes in marker popup when populated
chriscrosstalk May 4, 2026
0b25638
fix(AI): vendor-aware AMD HSA override + benchmark discrete-GPU detec…
chriscrosstalk May 5, 2026
c8f675f
chore: trigger release [rc2]
jakeaturner May 5, 2026
38b7142
chore(release): 1.32.0-rc.2 [skip ci]
jakeaturner May 5, 2026
525a1f1
fix(System): correct NVIDIA VRAM in Graphics card (#835)
bgauger May 8, 2026
0a7bd9b
fix(AI): preserve semver tag in DB on AMD Ollama updates
chriscrosstalk May 11, 2026
e42f933
fix(Downloads): treat missing Content-Type as octet-stream (#848)
bgauger May 8, 2026
adb132c
chore(release): 1.32.0-rc.1 [skip ci]
cosmistack-bot May 12, 2026
b43fea3
chore(release): 1.32.0-rc.3 [skip ci]
jakeaturner May 12, 2026
5a72560
fix(AI): rewrite RAG query on first follow-up (off-by-one in skip-rew…
chriscrosstalk May 12, 2026
7acc534
fix(RAG): unbreak multi-batch ZIM ingestion (jobId dedupe)
chriscrosstalk May 13, 2026
6778fe6
chore(release): 1.32.0-rc.4 [skip ci]
jakeaturner May 13, 2026
e51ead6
fix(queue): singleton QueueService to stop ioredis connection leak
chriscrosstalk May 13, 2026
ba661a9
fix(RAG): pace continuation batches when embedding is CPU-only
chriscrosstalk May 13, 2026
fe51dc4
feat(GPU): auto-remediate nomad_ollama passthrough loss on admin boot…
chriscrosstalk May 13, 2026
63170df
fix(DockerService): improve volume logic and documentation in forceRe…
jakeaturner May 13, 2026
0390e95
fix(System): correct AMD VRAM in Graphics card + harden log probe
chriscrosstalk May 13, 2026
4f82b69
fix(System): validate StartedAt with fallback to tail:500 (PR review)
chriscrosstalk May 13, 2026
fe59917
fix(RAG): report ZIM ingestion progress in overall-file frame
chriscrosstalk May 13, 2026
d621761
fix(KB): add re-embed and reset & rebuild opts to fix broken embeddin…
jakeaturner May 16, 2026
5193f74
fix(ZIM): preserve co-existing Wikipedia corpora on cleanup (#884)
chriscrosstalk May 14, 2026
69cf66c
feat(KB): per-file ingest state machine (Phase 1 of RFC #883) (#888)
chriscrosstalk May 16, 2026
68c0a37
fix(RAG): anchor continuation-batch initial progress to overall-file …
chriscrosstalk May 16, 2026
c9ccd4a
fix(AI): pre-cap embed input + log fallback reason (#881)
chriscrosstalk May 14, 2026
8ce5790
fix(AI): add truncation DEBUG log
jakeaturner May 16, 2026
68e1bd5
feat(KB): ratio registry for disk + time estimates (Phase 1B of RFC #…
chriscrosstalk May 14, 2026
460065a
fix(KB): align chunks_per_mb column type with TS contract
jakeaturner May 17, 2026
7d7459b
feat(KB): group admin docs into single row in Stored Files (RFC #883 §9)
chriscrosstalk May 14, 2026
ca5569c
feat(KB): status pill + last-activity timestamp on Processing Queue (…
chriscrosstalk May 14, 2026
603a707
feat(KB): Always/Manual ingest policy toggle (RFC #883 §1/§4) (#894)
chriscrosstalk May 17, 2026
ab8281d
feat(KB): surface embedding-disk estimate in curated tier-change moda…
chriscrosstalk May 14, 2026
7c2282a
feat(KB): conditional warnings A + B on Stored Files (RFC #883 §6)
chriscrosstalk May 14, 2026
cbd86b7
refactor(KB): move FileWarning to shared types/rag following existing…
jakeaturner May 17, 2026
cbae48a
fix(KB): surface file-warning compute failures instead of masking as …
jakeaturner May 17, 2026
5fcbbc5
fix(KB): remove redundant Refresh button from Processing Queue
chriscrosstalk May 14, 2026
4479919
fix(KB): union Stored Files list with state-machine file paths (#898)
chriscrosstalk May 17, 2026
60e7d45
feat(KB): first-chat JIT prompt for ingest policy (RFC #883 Phase 3 t…
chriscrosstalk May 14, 2026
857eb00
fix(KB): silent maybe-later error + redundant prompt-state refetches …
jakeaturner May 17, 2026
fa7cdbb
feat(KB): wizard AI policy step (RFC #883 Phase 3 task 13)
chriscrosstalk May 14, 2026
21d9929
feat(KB): guardrail modal at 50GB / 10%-free thresholds (RFC #883 §7)
chriscrosstalk May 14, 2026
47e6c13
fix(KB): guardrail bypass during estimate load + Transition sibling (…
jakeaturner May 17, 2026
d4623c6
chore(release): 1.32.0-rc.5 [skip ci]
jakeaturner May 17, 2026
be91b55
fix(KB): blank-screen on panel open + tooltips on bulk-action buttons
chriscrosstalk May 17, 2026
d357f32
feat(easy-setup): split AI into its own conditional step (issue #905)
chriscrosstalk May 17, 2026
75f0091
feat(KB): per-file ingest action + state indicator on Stored Files (R…
chriscrosstalk May 18, 2026
e77285d
refactor(KB): typed failure codes for embedSingleFile + accurate HTTP…
jakeaturner May 18, 2026
4f54fbe
chore(release): 1.32.0-rc.6 [skip ci]
jakeaturner May 18, 2026
6e14475
feat(chat): confirm-on-switch + one-chat-model-at-a-time enforcement
chriscrosstalk May 18, 2026
d04cf37
refactor(AI): single source of truth for embedding model name
jakeaturner May 19, 2026
0e5fe07
fix(KB): TierSelectionModal hook order + register IconLibrary
chriscrosstalk May 18, 2026
1dd7618
fix(content): show selected tier on cards while downloads are in flight
chriscrosstalk May 19, 2026
0ad4b5f
fix(KB): respect Manual ingest policy on post-download dispatch
chriscrosstalk May 19, 2026
ac791f7
fix(models): correct inverted belongsTo keys on ChatMessage.session (…
jakeaturner May 20, 2026
2125f99
fix(AI): improve remote Ollama url validation to prevent SSRF vulnera…
jakeaturner May 20, 2026
4cf24d3
fix(security): match IPv6 SSRF patterns against unbracketed hostnames
jakeaturner May 20, 2026
03fc29e
fix(security): canonicalize hostnames to block IPv4-mapped IPv6 IMDS …
jakeaturner May 20, 2026
0760cf0
chore(deps): pin ipaddr.js version
jakeaturner May 20, 2026
27a3d82
docs: update release notes
jakeaturner May 20, 2026
ba2b44c
build(deps-dev): bump @adonisjs/tsconfig from 1.4.1 to 2.0.0 in /admin
dependabot[bot] May 20, 2026
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
11 changes: 9 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,14 @@ We are committed to providing a welcoming environment for everyone. Disrespectfu

## Before You Start

**Open an issue first.** Before writing any code, please [open an issue](../../issues/new) to discuss your proposed change. This helps avoid duplicate work and ensures your contribution aligns with the project's direction.
**Open an issue first.** Before writing any code for a non-trivial change, you must [open an issue](../../issues/new) to discuss your proposed change. This helps avoid duplicate work and ensures your contribution aligns with the project's direction. **Pull requests submitted without a corresponding issue may be closed at the maintainers' discretion.**

**Trivial fixes are exempt** and may be submitted directly as a PR. Examples:
- Typo and grammar corrections
- Documentation clarifications
- Small one-line bug fixes with an obvious cause

If you're not sure whether your change qualifies as trivial, open an issue first.

When opening an issue:
- Use a clear, descriptive title
Expand Down Expand Up @@ -149,7 +156,7 @@ This project uses [Semantic Versioning](https://semver.org/). Versions are manag
2. Open a pull request against the `dev` branch of this repository
3. In the PR description:
- Summarize what your changes do and why
- Reference the related issue (e.g., `Closes #123`)
- Reference the related issue (e.g., `Closes #123`) — required for non-trivial changes
- Note any relevant testing steps or environment details
4. Be responsive to feedback — maintainers may request changes. Pull requests with no activity for an extended period may be closed.

Expand Down
40 changes: 37 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
FROM node:22-slim AS base

# Install bash & curl for entrypoint script compatibility, graphicsmagick for pdf2pic, and vips-dev & build-base for sharp
RUN apt-get update && apt-get install -y bash curl graphicsmagick libvips-dev build-essential
RUN apt-get update && apt-get install -y \
bash \
curl \
graphicsmagick \
libvips-dev \
build-essential \
pciutils \
&& rm -rf /var/lib/apt/lists/*

# All deps stage
FROM base AS deps
Expand All @@ -27,6 +34,31 @@ FROM base
ARG VERSION=dev
ARG BUILD_DATE
ARG VCS_REF
ARG TARGETARCH

# go-pmtiles (regional map extracts). Pinned so the CLI's stdout format stays
# in sync with parseDryRunOutput().
ARG PMTILES_VERSION=1.30.2
# Upstream releases don't ship a checksums file, so pin per-arch SHA256 here.
# When bumping PMTILES_VERSION, regenerate these with:
# curl -fsSL <release-url> | sha256sum
ARG PMTILES_SHA256_AMD64=2cd3aa18868297fc88425038f794efdc0995e0275f4ca16fa496dd79e245a40c
ARG PMTILES_SHA256_ARM64=804cdf071834e1156af554c1a26cc42b56b9cde5a2db9c6e3653d16fb846d5fa
RUN set -eux; \
case "${TARGETARCH:-amd64}" in \
amd64) PMTILES_ARCH=x86_64; PMTILES_SHA256="${PMTILES_SHA256_AMD64}" ;; \
arm64) PMTILES_ARCH=arm64; PMTILES_SHA256="${PMTILES_SHA256_ARM64}" ;; \
*) echo "Unsupported TARGETARCH: ${TARGETARCH}" >&2; exit 1 ;; \
esac; \
TARBALL="go-pmtiles_${PMTILES_VERSION}_Linux_${PMTILES_ARCH}.tar.gz"; \
cd /tmp; \
curl -fsSL -o "$TARBALL" \
"https://github.com/protomaps/go-pmtiles/releases/download/v${PMTILES_VERSION}/${TARBALL}"; \
echo "${PMTILES_SHA256} ${TARBALL}" | sha256sum -c -; \
tar -xzf "$TARBALL" -C /usr/local/bin pmtiles; \
rm -f "$TARBALL"; \
chmod +x /usr/local/bin/pmtiles; \
/usr/local/bin/pmtiles version

# Labels
LABEL org.opencontainers.image.title="Project N.O.M.A.D" \
Expand All @@ -43,8 +75,10 @@ ENV NODE_ENV=production
WORKDIR /app
COPY --from=production-deps /app/node_modules /app/node_modules
COPY --from=build /app/build /app
# Copy root package.json for version info
COPY package.json /app/version.json
# Generate version.json from the VERSION build-arg so the image tag is the
# single source of truth (previously copied root package.json, which drifted
# from the tag when semantic-release did not commit the bump back).
RUN echo "{\"version\":\"${VERSION}\"}" > /app/version.json

# Copy docs and README for access within the container
COPY admin/docs /app/docs
Expand Down
6 changes: 4 additions & 2 deletions FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,17 @@ Long answer: Custom storage paths, mount points, and external drives (like iSCSI

## Can I run NOMAD on MAC, WSL2, or a non-Debian-based Distro?

See [Why does NOMAD require a Debian-based OS?](#why-does-nomad-require-a-debian-based-os)
**WSL2 on Windows** is community-supported via the [WSL2 install guide](https://www.projectnomad.us/install/wsl2) — covers two install paths (native Docker and Docker Desktop) with all known gotchas documented and empirical performance numbers comparing WSL2 to bare-metal.

**macOS and other non-Debian Linux distros** aren't officially supported. See [Why does NOMAD require a Debian-based OS?](#why-does-nomad-require-a-debian-based-os) for details.

## Why does NOMAD require a Debian-based OS?

Project N.O.M.A.D. is currently designed to run on Debian-based Linux distributions (with Ubuntu being the recommended distro) because our installation scripts and Docker configurations are optimized for this environment. While it's technically possible to run the Docker containers on other operating systems that support Docker, we have not tested or optimized the installation process for non-Debian-based systems, so we cannot guarantee a smooth experience on those platforms at this time.

Support for other operating systems will come in the future, but because our development resources are limited as a free and open-source project, we needed to prioritize our efforts and focus on a narrower set of supported platforms for the initial release. We chose Debian-based Linux as our starting point because it's widely used, easy to spin up, and provides a stable environment for running Docker containers.

Community members have provided guides for running N.O.M.A.D. on other platforms (e.g. WSL2, Mac, etc.) in our Discord community and [Github Discussions](https://github.com/Crosstalk-Solutions/project-nomad/discussions), so if you're interested in running N.O.M.A.D. on a non-Debian-based system, we recommend checking there for any available resources or guides. However, keep in mind that if you choose to run N.O.M.A.D. on a non-Debian-based system, you may encounter issues that we won't be able to provide support for, and you may need to have a higher level of technical expertise to troubleshoot and resolve any problems that arise.
For Windows users, the [WSL2 install guide](https://www.projectnomad.us/install/wsl2) provides a community-supported path. Community members have also published guides for other platforms (e.g. macOS) in our Discord community and [Github Discussions](https://github.com/Crosstalk-Solutions/project-nomad/discussions), so if you're interested in running N.O.M.A.D. on a non-Debian-based system, we recommend checking there for any available resources or guides. However, keep in mind that if you choose to run N.O.M.A.D. on a non-Debian-based system, you may encounter issues that we won't be able to provide support for, and you may need to have a higher level of technical expertise to troubleshoot and resolve any problems that arise.

## Can I run NOMAD on a Raspberry Pi or other ARM-based device?
Project N.O.M.A.D. is currently designed to run on x86-64 architecture, and we have not yet tested or optimized it for ARM-based devices like the Raspberry Pi (and have not published any official images for ARM architecture).
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ sudo bash install_nomad.sh

Project N.O.M.A.D. is now installed on your device! Open a browser and navigate to `http://localhost:8080` (or `http://DEVICE_IP:8080`) to start exploring!

For a complete step-by-step walkthrough (including Ubuntu installation), see the [Installation Guide](https://www.projectnomad.us/install).
For a complete step-by-step walkthrough (including Ubuntu installation), see the [Installation Guide](https://www.projectnomad.us/install). For Windows users, see the [WSL2 install guide](https://www.projectnomad.us/install/wsl2) — community-supported path covering native Docker and Docker Desktop install routes.

### Advanced Installation
For more control over the installation process, copy and paste the [Docker Compose template](https://raw.githubusercontent.com/Crosstalk-Solutions/project-nomad/refs/heads/main/install/management_compose.yaml) into a `docker-compose.yml` file and customize it to your liking (be sure to replace any placeholders with your actual values). Then, run `docker compose up -d` to start the Command Center and its dependencies. Note: this method is recommended for advanced users only, as it requires familiarity with Docker and manual configuration before starting.
Expand Down Expand Up @@ -124,6 +124,7 @@ Contributions are welcome and appreciated! Please see [CONTRIBUTING.md](CONTRIBU
- **Benchmark Leaderboard:** [benchmark.projectnomad.us](https://benchmark.projectnomad.us) - See how your hardware stacks up against other NOMAD builds
- **Troubleshooting Guide:** [TROUBLESHOOTING.md](TROUBLESHOOTING.md) - Find solutions to common issues
- **FAQ:** [FAQ.md](FAQ.md) - Find answers to frequently asked questions
- **Community Add-Ons:** [admin/docs/community-add-ons.md](admin/docs/community-add-ons.md) - Third-party content packs built by the community

## License

Expand Down
7 changes: 7 additions & 0 deletions admin/adonisrc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ export default defineConfig({
() => import('@adonisjs/transmit/transmit_provider'),
() => import('#providers/map_static_provider'),
() => import('#providers/kiwix_migration_provider'),
() => import('#providers/qdrant_restart_policy_provider'),
() => import('#providers/version_check_provider'),
() => import('#providers/gpu_passthrough_remediation_provider'),
],

/*
Expand Down Expand Up @@ -106,6 +109,10 @@ export default defineConfig({
pattern: 'resources/views/**/*.edge',
reloadServer: false,
},
{
pattern: 'resources/geodata/**/*.geojson',
reloadServer: false,
},
{
pattern: 'public/**',
reloadServer: false,
Expand Down
7 changes: 5 additions & 2 deletions admin/app/controllers/benchmark_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { runBenchmarkValidator, submitBenchmarkValidator } from '#validators/ben
import { RunBenchmarkJob } from '#jobs/run_benchmark_job'
import type { BenchmarkType } from '../../types/benchmark.js'
import { randomUUID } from 'node:crypto'
import logger from '@adonisjs/core/services/logger'

@inject()
export default class BenchmarkController {
Expand Down Expand Up @@ -52,9 +53,10 @@ export default class BenchmarkController {
result,
})
} catch (error) {
logger.error({ err: error }, '[BenchmarkController] Benchmark run failed')
return response.status(500).send({
success: false,
error: error.message,
error: 'An internal error occurred while running the benchmark.',
})
}
}
Expand Down Expand Up @@ -181,9 +183,10 @@ export default class BenchmarkController {
} catch (error) {
// Pass through the status code from the service if available, otherwise default to 400
const statusCode = (error as any).statusCode || 400
logger.error({ err: error }, '[BenchmarkController] Benchmark submit failed')
return response.status(statusCode).send({
success: false,
error: error.message,
error: 'Failed to submit benchmark results.',
})
}
}
Expand Down
19 changes: 13 additions & 6 deletions admin/app/controllers/chats_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { createSessionSchema, updateSessionSchema, addMessageSchema } from '#val
import KVStore from '#models/kv_store'
import { SystemService } from '#services/system_service'
import { SERVICE_NAMES } from '../../constants/service_names.js'
import logger from '@adonisjs/core/services/logger'

@inject()
export default class ChatsController {
Expand Down Expand Up @@ -45,8 +46,9 @@ export default class ChatsController {
const session = await this.chatService.createSession(data.title, data.model)
return response.status(201).json(session)
} catch (error) {
logger.error({ err: error }, '[ChatsController] Failed to create session')
return response.status(500).json({
error: error instanceof Error ? error.message : 'Failed to create session',
error: 'Failed to create session',
})
}
}
Expand All @@ -56,8 +58,9 @@ export default class ChatsController {
const suggestions = await this.chatService.getChatSuggestions()
return response.status(200).json({ suggestions })
} catch (error) {
logger.error({ err: error }, '[ChatsController] Failed to get suggestions')
return response.status(500).json({
error: error instanceof Error ? error.message : 'Failed to get suggestions',
error: 'Failed to get suggestions',
})
}
}
Expand All @@ -69,8 +72,9 @@ export default class ChatsController {
const session = await this.chatService.updateSession(sessionId, data)
return session
} catch (error) {
logger.error({ err: error }, '[ChatsController] Failed to update session')
return response.status(500).json({
error: error instanceof Error ? error.message : 'Failed to update session',
error: 'Failed to update session',
})
}
}
Expand All @@ -81,8 +85,9 @@ export default class ChatsController {
await this.chatService.deleteSession(sessionId)
return response.status(204)
} catch (error) {
logger.error({ err: error }, '[ChatsController] Failed to delete session')
return response.status(500).json({
error: error instanceof Error ? error.message : 'Failed to delete session',
error: 'Failed to delete session',
})
}
}
Expand All @@ -94,8 +99,9 @@ export default class ChatsController {
const message = await this.chatService.addMessage(sessionId, data.role, data.content)
return response.status(201).json(message)
} catch (error) {
logger.error({ err: error }, '[ChatsController] Failed to add message')
return response.status(500).json({
error: error instanceof Error ? error.message : 'Failed to add message',
error: 'Failed to add message',
})
}
}
Expand All @@ -105,8 +111,9 @@ export default class ChatsController {
const result = await this.chatService.deleteAllSessions()
return response.status(200).json(result)
} catch (error) {
logger.error({ err: error }, '[ChatsController] Failed to delete all sessions')
return response.status(500).json({
error: error instanceof Error ? error.message : 'Failed to delete all sessions',
error: 'Failed to delete all sessions',
})
}
}
Expand Down
40 changes: 38 additions & 2 deletions admin/app/controllers/maps_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
assertNotPrivateUrl,
downloadCollectionValidator,
filenameParamValidator,
mapExtractPreflightValidator,
mapExtractValidator,
remoteDownloadValidator,
remoteDownloadValidatorOptional,
} from '#validators/common'
Expand Down Expand Up @@ -87,6 +89,28 @@ export default class MapsController {
}
}

async listCountries({}: HttpContext) {
return { countries: await this.mapService.listCountries() }
}

async listCountryGroups({}: HttpContext) {
return { groups: await this.mapService.listCountryGroups() }
}

async extractPreflight({ request }: HttpContext) {
const payload = await request.validateUsing(mapExtractPreflightValidator)
return await this.mapService.extractPreflight(payload)
}

async extractRegion({ request }: HttpContext) {
const payload = await request.validateUsing(mapExtractValidator)
const result = await this.mapService.extractRegion(payload)
return {
message: 'Extract started successfully',
...result,
}
}

async styles({ request, response }: HttpContext) {
// Automatically ensure base assets are present before generating styles
const baseAssetsExist = await this.mapService.ensureBaseAssets()
Expand Down Expand Up @@ -137,9 +161,11 @@ export default class MapsController {
vine.compile(
vine.object({
name: vine.string().trim().minLength(1).maxLength(255),
longitude: vine.number(),
latitude: vine.number(),
longitude: vine.number().min(-180).max(180),
latitude: vine.number().min(-90).max(90),
color: vine.string().trim().maxLength(20).optional(),
notes: vine.string().trim().nullable().optional(),
marker_type: vine.string().trim().maxLength(20).optional(),
})
)
)
Expand All @@ -148,6 +174,8 @@ export default class MapsController {
longitude: payload.longitude,
latitude: payload.latitude,
color: payload.color ?? 'orange',
notes: payload.notes ?? null,
marker_type: payload.marker_type ?? 'pin',
})
return marker
}
Expand All @@ -163,11 +191,19 @@ export default class MapsController {
vine.object({
name: vine.string().trim().minLength(1).maxLength(255).optional(),
color: vine.string().trim().maxLength(20).optional(),
longitude: vine.number().min(-180).max(180).optional(),
latitude: vine.number().min(-90).max(90).optional(),
notes: vine.string().trim().nullable().optional(),
marker_type: vine.string().trim().maxLength(20).optional(),
})
)
)
if (payload.name !== undefined) marker.name = payload.name
if (payload.color !== undefined) marker.color = payload.color
if (payload.longitude !== undefined) marker.longitude = payload.longitude
if (payload.latitude !== undefined) marker.latitude = payload.latitude
if (payload.notes !== undefined) marker.notes = payload.notes
if (payload.marker_type !== undefined) marker.marker_type = payload.marker_type
await marker.save()
return marker
}
Expand Down
Loading