Skip to content

Breaking/hotfix 1#25

Open
codeGlaze wants to merge 97 commits intodevelopfrom
breaking/hotfix-1
Open

Breaking/hotfix 1#25
codeGlaze wants to merge 97 commits intodevelopfrom
breaking/hotfix-1

Conversation

@codeGlaze
Copy link
Owner

test with ci

Dependency upgrades: Clojure 1.12.4, ClojureScript 1.12.134,
Pedestal 0.7.0, Datomic Pro 1.0.7482, React 18.3.1, Reagent 2.0.1,
re-frame 1.4.4, PDFBox 3.0.6, Buddy 3.x, figwheel-main 0.2.20,
java-time 1.4.2, and supporting library updates.

Key changes:
- Datomic Free -> Pro (Java 21 compatibility)
- Pedestal interceptor wrapping + CSP nonce handling (required by 0.7)
- React 18 createRoot migration
- clj-time -> java-time
- lein-figwheel -> figwheel-main
- CI updated to Java 21
- Devcontainer + scripts for Datomic Pro setup

74 tests, 237 assertions, 0 failures.
Migration index + per-topic docs covering Pedestal 0.7 (CSP, interceptor
wrapping, Jetty 11 pin), Datomic Pro, React 18/Reagent 2, library upgrades,
dev tooling, Java 21 compatibility, and environment variables.

Also fixes CI workflow Java version 8 → 21.
Move dev_init.clj and dev_tools.clj into dev/user.clj so dev tooling
stays off the production classpath (src/clj/ is AOT-compiled into the
uberjar). The user namespace now serves as both REPL helper and CLI
entrypoint via -main dispatch.

- user.clj: add :gen-class, conn helper, user CRUD, -main CLI
- project.clj: :init-db profile includes dev/ in source-paths
- scripts: rewire start.sh, create_dummy_user.sh, dev-setup.sh
- docs/migration/dev-tooling.md: rewrite for Clojure newcomers
- README.md: full overhaul for modern stack (Java 21, Datomic Pro,
  Pedestal 0.7, React 18, figwheel-main)
- Delete src/clj/orcpub/dev_init.clj and dev_tools.clj
Frontend:
- Fix message component white-on-white text (Garden CSS class)
- Fix login form input alignment (Garden CSS class)
- Fix favicon.clj 196→192 size typo
- Use :class instead of :class-name (Reagent 2.x merge behavior)

Build:
- Add externs.js for React 18 APIs (ReactDOM.Root.render, flushSync)
- Upgrade cljs-http 0.1.45→0.1.49 (fixes no.en.core shadowing warnings)
- Switch to lambdaisland/garden 1.9.606 (fixes clojure.core/abs shadowing)
- Add simplelogger.properties to suppress PDFBox font fallback WARN
- Add fonts-liberation to Dockerfile (root cause fix for font fallback)
- All builds now 0 errors, 0 warnings

Dev tooling:
- CSP nonce interceptor is no-op in dev mode (eliminates console spam)
- Figwheel uses fig:watch (headless) via start.sh; fig:dev for interactive
- menu CLI for user management (create/verify/delete with .test-users log)
- dev-setup.sh auto-creates test user (--no-test-user to skip)
- Updated migration docs (CSP behavior, core shadowing, externs, figwheel modes)
Extract pure compute helpers to compute.cljc and shared utils to
event_utils.cljc (moved from .cljs). Replace all 12 instances of
@(subscribe [...]) inside event handlers with direct db reads,
component-passed parameters, or replicated computation chains.

Adds autosave_fx.cljs with track!-based template caching for the
autosave handler that previously depended on @(subscribe [:built-character]).
Add fig:test alias and test.cljs.edn for figwheel-based CLJS testing.
New tests: compute_test.cljc (plugin vals, spell/item filtering, sort
order), event_utils_test.cljc (auth headers, mod config), events_test.cljs
(re-frame handler integration via dispatch-sync). Fix character_test.cljc
for CLJS compatibility with reader conditionals around JVM-only APIs.
Reagent 2.x changed :class-name behavior — it now OVERWRITES hiccup
tag classes instead of merging them. This caused widespread visual
regressions where base CSS classes on elements were silently dropped.

114 hiccup prop instances fixed across 6 files. Data map :class-name
keys (D&D class names in character/template/spell data) left unchanged.
22 subscribe calls in options.cljc prereq-fn closures replaced with
direct character/* pure function calls. These were never reactive —
the subscribe signal wrapped the passed entity in a plain atom. Now
prereq-fns receive built-char directly from callers (views_aux,
character_builder, entity) matching the old data flow exactly.

Also: fix meets-prereqs? when/if bug, overflow-x:hidden for
horizontal scroll, user.clj clean exit, search-input-keypress fix.
…cljc

7 subscribe calls in prereq-fn closures replaced with direct
char5e/ability-values and char5e/spells-known calls. Also removed
unused re-frame.core/subscribe import.
Phase 2: 13 subscribes across options.cljc, pdf_spec.cljc,
equipment_subs.cljs, and views.cljs replaced with pure functions,
parameter threading, plugin-data maps, and reg-sub-raw.

pdf_spec.cljc is now fully pure — no re-frame dependency.
options.cljc threads race-map from caller instead of subscribing.
equipment_subs ::mi5e/item converted to reg-sub-raw for conditional sub.

Also fixes input-field flickering in components.cljc — tracks
:prev-value to clear temp-val only when parent value catches up,
instead of clearing in setTimeout (which raced with Reagent 2.x
synchronous rendering).
Tests cover the SSOT pure functions and parameter threading changes
from the subscribe refactor:

- compute-all-weapons-map: PHB weapons, magic weapon merge, custom
  weapon expansion, nil/empty equivalence, custom doesn't clobber base
- feat-prereqs: exact label assertions for ability/spellcasting/armor
  prereqs, race-map parameter threading, mixed prereq combinations
- pdf_spec: class-string formatting (single/multi/subclass/empty),
  entity-vals key mapping and rename behavior

123 tests, 332 assertions, 0 failures.
…tion

input-field now dispatches on every keystroke. The expensive
entity/build call is debounced in the :built-character subscription
with leading+trailing edge: first change computes immediately
(dropdowns stay snappy), rapid keystrokes batch until 500ms quiet.

input-field keeps a minimal local atom to buffer typed text and
prevent controlled-input flicker while re-frame propagates.
option-language-proficiency-choice used def+partial which evaluated
@(subscribe [::langs/languages]) at namespace load time, outside any
reactive context. Converted to defn so subscribe runs during render.
Merges 24 commits from origin/develop:
- Character folders feature (13 commits)
- Equipment/weapon fixes: special, loading properties (5 commits)
- Docker verified users and setup scripts (3 commits)
- Additional test coverage

Conflict resolutions:
- views.cljs: merged folder UI with subscribe refactor + :class-name fixes
- docker-compose*.yaml: kept ${VAR:-default} pattern with datomic:dev:// URLs
- magic_items_test.clj: kept both compute-all-weapons-map and weapon property tests
- pdf_spec.cljc: threaded all-magic-items-map through plugin-data (new subscribe from develop)

Post-merge fixes:
- 4 new :class-name → :class conversions in folder/filter code (Reagent 2.x)
- Added :all-magic-items-map to plugin-data assembly in views.cljs
- Fix events/show-generic-error undefined alias in subs.cljs
- Add on-failure handlers to all folder HTTP ops (re-fetch on error)
- Client + server validation: reject blank folder names
- Wrap check-folder-owner with interceptor/interceptor, add 404
- Use named tempid in create-folder (d/resolve-tempid)
- Add default clause to folders subscription case statement
- Fix builder-dropdown CSS class (undefined → builder-option-dropdown)
- Add 3 server-side tests: blank rejection, trim, nil-name default
- Update MIGRATION-INDEX test counts, frontend-stack subscribe totals
- Add docs/STACK.md: library/dependency onboarding guide
Delete 4 static map wrapper subs (weapons-map, armor-map, equipment-map,
treasure-map) superseded by homebrew-aware versions. Reader-discard 7
unused subs with explanatory comments. All pre-existing tech debt.
Use event-utils/show-generic-error instead of the def alias that
appears later in the file. Brings lint errors from 1 to 0.
591 if-without-else converted to when/when-let/when-not across 33 files.
Resolved 11 merge conflicts (re-ran fix script on breaking's versions).
Fixed 2 pre-existing bugs: when with implicit do discarding first expr
in classes.cljc (ranger terrain) and options.cljc (spell level title).

Lint: 0 errors, 0 warnings. Tests: 174/444/0.
- Move all linter config from project.clj :lint profile to .clj-kondo/config.edn
  (single source of truth for both IDE and CLI)
- Expand lint scope: src, native, test, web (was src only)
- Bump clj-kondo 2024.05.22 → 2026.01.19
- Fix deprecated :if → :missing-else-branch linter name
- Add :clojure-lsp/unused-public-var :exclude for live false-positives
- Add :exclude-when-defined-by for re-frame registration macros
- Add shadowed-var :exclude list for intentional shadows
#_ discard 43 dead vars:
- common.cljc (4): ptime, hours-per-day, rounds-to-hours, rounds-to-minutes
- character.cljc (6): add-namespaces + 2 cascade helpers, base-climbing-speed,
  saving-throw-advantages, max-armor-class
- classes.cljc (4): blessings-of-knowledge-skill, spell-level-to-cleric-level,
  spell-in-spells-known?, pact-weapon-option
- options.cljc (15): deprecated ua/scag refs, #_ template refs, zero-caller defs
- template.cljc (14): ability roller UI (superseded by character_builder.cljs),
  amazon frames, content-list, custom-race-builder;
  #_ subscribe/dispatch refers (no live callers remain)

Redundant expression fixes:
- classes.cljc: remove nested (str (str ...))
- options.cljc: flatten (and (and ...)) in dual-wield checks,
  remove duplicate source destructuring param
#_ discard 49 dead vars:
- views.cljs (25): dead style defs, duplicate constants, superseded components
- events.cljs (22): dead defs (max-iterations, dnd-5e-characters-path,
  validate-registration, set-active-tabs, remove-subtypes, compute aliases),
  17 never-dispatched reg-event-db/fx handlers
- db.cljs (1): musical-instrument-choice-cfg (duplicate of classes.cljc)
- subs.cljs (1): ::char5e/summary reg-sub (never subscribed to)

Redundant expression fixes:
- views.cljs, character_builder.cljs, events.cljs: remove (str "literal")
Native:
- Remove unused refers (atom, subscribe, dispatch, dispatch-sync)
- Add missing font-size param to remaining-bubble
- if→when for side-effect-only branches

Web:
- if→when for protocol redirect and route matching

Tests:
- Narrow :refer lists (deftest/is only, remove unused diff/testing)
- Fix misindented (* 2 v) in entity_spec_test
- if→when in event_handlers_test

Registration:
- Remove unreachable {} before cond-> in validate-registration

Docs:
- CHANGELOG: document lint commits (if→when, forward-ref fix), update status
- MIGRATION-INDEX: update lint status to 0 errors, 0 warnings
Merge feature/error-handling-import-validation into breaking/2026-stack-modernization.
29 conflicting files resolved, 21 new files auto-merged, 206 tests passing.

New features: import/export validation pipeline, email change flow,
missing content detection, conflict resolution UI, backend error handling,
nil guards in PDF/routes, orcbrew CLI tool.

Post-merge fixes: handle-api-response moved to event_utils.cljc,
srd-link un-discarded, key-to-name → common/kw-to-name,
:class-name → :class for Reagent 2.x, hiccup2 str wrapping.
Auto-merged content_reconciliation.cljs references these functions
but they didn't survive the merge into common.cljc. Restored from
feature branch. 0 CLJS warnings, 206 JVM tests passing.
…ions

::char5e/template is used by autosave_fx.cljs and as input signal
for ::char5e/built-template. ::char5e/summary-map is used by the
combat tracker in views.cljs. Both were false-positive dead code.
header-tab: on-mouse-over/out → on-mouse-enter/leave to prevent
menu from disappearing when cursor moves from button to dropdown.
mouse-enter/leave doesn't fire between parent and child elements.

dropdown: map → map-indexed with index-prefixed keys to handle
duplicate option values from homebrew plugin data (e.g.,
:alchemical-homunculus appearing twice in the same selection).
Builder: block save when option names are empty or duplicated, with
inline red borders and error messages on offending fields. Import
pipeline: dedup identical options silently, rename different-content
same-name options with number suffixes. Dropdown: distinct-by safety
net for pre-existing data in localStorage.
set-combat-path-prop now falls back to default-combat when the path
interceptor extracts nil, preventing assoc-in from building maps with
integer keys instead of vectors. Also improves the invalid-item log
message to include the localStorage key name for easier debugging.

Adds docs/TODO.md to track the broader localStorage cleanup strategy.
4 static equipment map subscriptions (weapons-map, armor-map,
equipment-map, treasure-map) were deleted during orphan cleanup but
are still used by character_builder's inventory-selector via dynamic
sub vectors. Restores them — fixes IDeref crash on equipment page.

Template cache init (autosave_fx) now retries if the subscription
isn't registered yet. In dev mode each namespace loads as a separate
script, and setTimeout 0 can fire before equipment_subs.cljs has
loaded — preventing the IDeref crash on cold page load.
…sitives

autosave_fx: require equipment-subs directly instead of retry logic.
This guarantees ::char5e/template sub is registered before the defonce
runs, so subscribe stays inside r/track! (reactive context, no warning).

content_reconciliation: remove catch-all that labeled everything under
a class path as "Class" content. Keys like :roll (HP method), :feat
(ASI choice), :great-weapon-fighting (fighting style), :intimidation
(skill pick) were being flagged as missing homebrew. Now only flags
keys at content-relevant depths: class at [:class], subclass at
[:class :archetype-type], race, subrace, background.
Rewrites LEIN-UBERJAR-HANG.md with the full research narrative:
all 12 attempts (7 cljsbuild profile isolation, figwheel-main
replacement, stale-namespaces, eval-in-leiningen, recursive jar
inclusion, auto-clean discovery), root causes, the final 3-step
Docker build fix, and explicit DO NOT list.
App takes ~110s to boot in CI (Datomic peer init, schema transact,
font cache build). Previous healthcheck (15s start + 20×5s = 115s)
expired right at the boundary. Increased to 60s start + 30×10s = 360s.
… app

Pedestal defaults ::http/host to "localhost" when unset, binding Jetty
to loopback only. This meant nginx (in the web container) couldn't proxy
to orcpub:8890, and the healthcheck failed because Java resolved
"localhost" to IPv6 ::1 while BusyBox wget tried IPv4 127.0.0.1.

- Add ::http/host "0.0.0.0" to prod-service-map (all interfaces)
- Add ::http/host "localhost" to dev overrides (preserve dev behavior)
- Healthcheck now hits /health endpoint with explicit 127.0.0.1
Replace fragile sed-chain approach (5 build-time + 6 runtime mutations) with
a complete, version-controlled template. Structural config (host, protocol,
dirs, memory tuning) is hardcoded; only 4 secrets use ${VAR} placeholders
substituted at container startup by start.sh.

- New docker/transactor.properties.template with full production config
- Rewrite deploy/start.sh: pure bash sed, exec for PID 1, password rotation
- Dockerfile transactor target: COPY template, remove all sed lines
- Add /backups directory to transactor image
…hcheck

- Both compose files: add ALT_HOST/ENCRYPT_CHANNEL env vars, /backups volume
- Build compose: add homebrew volume to web (was missing vs legacy)
- Legacy compose: fix healthcheck to use /health + 127.0.0.1 + correct timing
- .env.example: add Transactor Tuning section with rotation vars
- docker-setup.sh: create backups/ dir, validate it, include tuning in .env
- New docs/DOCKER.md: architecture, compose files, Option C template approach,
  host=datomic rationale, Jetty binding, healthcheck strategy, memory tuning,
  volumes, Swarm migration notes, and file inventory
- Update ENVIRONMENT.md: add Docker/Transactor variables section (ALT_HOST,
  ENCRYPT_CHANNEL, password rotation) and deploy/start.sh to files table
- Fix /log vs /logs mount mismatch — transactor logs were lost on restart
- Escape \, &, | in sed replacements so passwords with special chars work
- Add chmod 600 on generated transactor.properties and .env files
- Add .env/.lein-env to .dockerignore — secrets no longer leak into build
- Run transactor as non-root datomic user, app as non-root app user
- Validate rotation passwords don't contain newlines (property injection)
- ENVIRONMENT.md: fix email var names (EMAIL_HOST→EMAIL_SERVER_URL etc),
  PORT default 8080→8890, note PORT tied to nginx.conf
- Both compose files: CMD-SHELL healthcheck with ${PORT:-8890} expansion,
  pass CSP_POLICY and DEV_MODE to orcpub container
- .env.example: add PORT-nginx note, ORCPUB_TAG reference
- docker-setup.sh: validate DATOMIC_PASSWORD matches DATOMIC_URL,
  double base64 output for reliable password length, docker compose v2 syntax
- Dockerfile: add VOLUME declarations for standalone docker run
- DOCKER.md: fix healthcheck example with tcp6 fallback
- nginx.conf: remove leftover PHP/FastCGI boilerplate from default template
New DOCKER-SECURITY.md with full reasoning for each decision:
non-root containers, sed replacement escaping, chmod 600, .dockerignore,
log dir naming, CMD-SHELL healthcheck, DATOMIC_URL sync, env passthrough,
VOLUME declarations.

Update DOCKER.md: add Security section, fix healthcheck example to show
CMD-SHELL, cross-reference DOCKER-SECURITY.md.
nginx.conf → nginx.conf.template with ${ORCPUB_PORT} placeholder.
Official nginx:alpine runs envsubst on /etc/nginx/templates/*.template
at startup, substituting only defined env vars (nginx's own $host,
$scheme, $remote_addr are safe).

All three PORT consumers now track a single .env value:
  Jetty (PORT env), healthcheck (CMD-SHELL ${PORT}), nginx (ORCPUB_PORT)

- Rename deploy/nginx.conf → deploy/nginx.conf.template
- Both compose: mount to /etc/nginx/templates/, pass ORCPUB_PORT
- Remove "PORT must match nginx" caveat from docs — no longer true
Two CI failures fixed:

1. /log permission denied — build-time chown is overridden by Docker bind
   mounts (host directory ownership wins). Switched to the standard
   entrypoint-chown-drop pattern: container starts as root, start.sh fixes
   ownership, su-exec drops to datomic user before exec-ing the transactor.

2. not-enough-memory — template had 4GB-tuned values (512m+512m=1024m)
   but the stock JVM uses -Xmx1g. Datomic requires (object-cache-max +
   memory-index-max) < 75% of heap. Lowered defaults to 1GB-appropriate
   values (128m+128m=256m < 768m).
…karound)

Datomic's restore-db and list-backups discover restore points by reading the
roots/ directory. On Windows, the JVM's directory enumeration can silently
fail, producing :restore/no-roots even though the backup is intact.

Both migration scripts now auto-discover the t value from the filesystem
(the numeric filename in roots/) and pass it explicitly as the 3rd argument
to restore-db. This bypasses the platform bug without affecting Linux/macOS.

Also adds filesystem fallback to do_verify() in both scripts, and documents
the Windows workaround in the migration troubleshooting guide.
The underlying issue is backup.clj calling Long.parseLong() on every
filename in roots/ without filtering — crashes on macOS .DS_Store,
silently fails on Windows. Referenced in script comments and migration
troubleshooting guide.
`lein uberjar` now compiles CLJS via figwheel-main as a prep-task,
so a single command produces a complete jar with compiled JS.
Previously CLJS had to be compiled separately (fig:prod) before
packaging, and the uberjar clean step would wipe it if you forgot.

Docker build is unaffected — uberjar-package profile uses ^:replace
on prep-tasks, so the 3-step build (CLJS, AOT+timeout, jar) is unchanged.
Reverts the figwheel prep-task addition from 077753c. `run` as a
prep-task in the :uberjar profile triggers the profile's own prep-tasks
recursively — lein enters an infinite build loop.

CLJS must remain a separate step: `lein fig:prod && lein uberjar`.
Docker is unaffected (uberjar-package uses ^:replace prep-tasks).
Chains fig:prod (CLJS) then uberjar in one command via `lein do`.
fig:prod runs without the :uberjar profile, avoiding the prep-task
infinite recursion that happens when `run` is a direct prep-task.
CLJS output (resources/public/) survives uberjar's clean (target/ only).
:clean-targets includes resources/public/js/compiled, so the uberjar
clean prep-task was wiping the CLJS output that fig:prod just built.

Fix: alias runs clean explicitly first, then fig:prod, then uberjar
with uberjar-noclean profile (skips redundant clean). Standalone
`lein uberjar` still cleans as before.
lein's jar/jar checks (:auto-clean project true) defaulting to true,
which runs clean before jar creation even when "clean" is removed from
prep-tasks. This deletes resources/public/js/compiled/ (CLJS output
from fig:prod) causing orcpub.js 404 in production.

Fix: add :auto-clean false to :uberjar profile, use ^:replace on
prep-tasks. Remove :uberjar-noclean (absorbed into :uberjar).
Simplify :uberjar-package (inherits auto-clean from :uberjar).
The monkey-patch on re-frame.core/subscribe used a variadic fn
(fn [query-v & args] ...) which doesn't implement IFn's 1-arity
.h method. In advanced compilation, all (subscribe [...]) call sites
compile to Y.h(vec) using 1-arity protocol dispatch, causing
"Y.h is not a function" TypeError on every render.
The inline script that fetches /homebrew.orcbrew ran unconditionally,
causing 400 errors when no server-side plugin endpoint exists. Now
only emits the fetch script when LOAD_HOMEBREW_URL is set. Also fixes
the protocol:// double-colon bug (window.location.protocol includes
the colon, so ${protocol}:// produced https:://).
- LEIN-UBERJAR-HANG.md: document :uberjar profile changes (auto-clean
  false moved from uberjar-package to uberjar), lein build alias,
  updated affected components table
- ENVIRONMENT.md: add LOAD_HOMEBREW_URL variable, add index.clj to
  files-that-read-environment table
- .env.example: add LOAD_HOMEBREW_URL (commented out by default)
- docker-compose files: add LOAD_HOMEBREW_URL passthrough
- core.cljs: clean up blank lines from debug wrapper removal
$(date +%m-%d-%Y) was never shell-expanded — it displayed as a
literal string. Now uses a CLJS self-referencing macro that runs
on the JVM at compile time, stamping the actual build date.
The nginx template hardcoded `orcpub` as the upstream hostname, which is
a Docker service name that only resolves inside Docker networks. Bare-metal
installs (e.g., Windows home server with native nginx) can't resolve it.

Introduce ORCPUB_HOST env var (defaults to `orcpub` for Docker) so
non-Docker setups can set it to 127.0.0.1.
DATOMIC_URL defaults to the Docker service name "datomic" which doesn't
resolve on bare-metal installs. Add commented-out localhost alternative
and a header note so users know to check hostnames when not using Docker.
script-tag only destructured :src and :nonce, silently dropping extra
attributes like :async and :crossorigin needed by the AdSense tag.
Changed to pass through all attributes.

CSP connect-src blocked Matomo tracker requests to t.dungeonmastersvault.com
and frame-src (defaulting to 'self') blocked Google ad iframes. Added the
required domains to connect-src and frame-src.
@github-actions
Copy link

github-actions bot commented Feb 26, 2026

All checks passed

Check Status Details
Lint Pass No errors
Tests Pass 206 tests, 948 assertions
CLJS Build Pass Compiled

Stack: Java 21 / figwheel-main / Datomic Pro

Full test output
/identity, :msec 0.346, :phase :end, :pid 2670, :tid 1}
[main] INFO datomic.process-monitor - {:metrics/started clojure.core/identity, :pid 2670, :tid 1}
[clojure-agent-send-off-pool-0] INFO datomic.domain - {:event :cache/create, :cache-bytes 2096103424, :pid 2670, :tid 27}
[clojure-agent-send-off-pool-0] INFO datomic.process-monitor - {:DbAddFulltextMsec {:lo 0, :hi 55, :sum 70, :count 15}, :AvailableMB 3820.0, :ObjectCacheCount 0, :event :metrics, :pid 2670, :tid 27}

lein test orcpub.dnd.e5-test

lein test orcpub.dnd.e5.char-filter-test

lein test orcpub.dnd.e5.character-test

lein test orcpub.dnd.e5.compute-test

lein test orcpub.dnd.e5.event-handlers-test

lein test orcpub.dnd.e5.event-utils-test

lein test orcpub.dnd.e5.favored-enemy-language-test

lein test orcpub.dnd.e5.folder-test

lein test orcpub.dnd.e5.magic-items-test

lein test orcpub.dnd.e5.options-test

lein test orcpub.dnd.e5.warlock-test

lein test orcpub.email-change-test
TEST_ERROR: Email send failed, rolling back pending state: SMTP down

lein test orcpub.entity-spec-test

lein test orcpub.entity-test

lein test orcpub.entity.strict-test

lein test orcpub.errors-test
TEST_ERROR: Failed email operation:
  Context: {:email user@example.com, :username alice, :message SMTP server unavailable}
TEST_ERROR: Failed database operation:
  Context: {:user-id 789, :message Connection timeout}
TEST_ERROR: Failed test operation:
  Context: {:user-id 456, :message Generic error}
TEST_ERROR: Failed test operation:
  Context: {:message Test error}
TEST_ERROR: Validation failed:
  Context: {:input abc}
TEST_ERROR: Validation failed:
  Context: {:data test}
TEST_ERROR: Test message
TEST_ERROR: Test message
  Context: {:id 123}

lein test orcpub.pdf-spec-test

lein test orcpub.pdf-test

lein test orcpub.routes-test

lein test orcpub.routes.folder-test

lein test orcpub.security-test

lein test orcpub.template-test

lein test orcpub.tools.orcbrew-test

Ran 206 tests containing 948 assertions.
0 failures, 0 errors.


Workflow run

Hand-edited analytics and ad tags were hardcoded in index.clj. Moved to
orcpub.integrations with defaults for DMV — forks override via .env or
set empty string to disable. Uses location.hostname so the same build
works across dev/staging/prod domains.
Make adsense-tag and matomo-tags private, expose one head-tags function
that index.clj calls. Adding future integrations only touches integrations.clj.
matomo-tags returns a list, which keep wrapped in another seq. Hiccup
doesn't recursively flatten nested seqs. Use concat to produce a flat
seq of hiccup vectors.
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.

1 participant