Feature/sdd - #165
Conversation
📝 WalkthroughWalkthroughThis change adds enhanced structured logging with Pino masking, credential redaction, trace correlation, repository and use-case events, updated environment configuration, feature specifications, observability configuration changes, refreshed coverage data, and generated Graphify artifacts. ChangesEnhanced flow logging
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant UseCase
participant Repository
participant Pino
participant OpenTelemetry
Client->>UseCase: execute authentication or management flow
UseCase->>Pino: log start, milestone, success, or failure
UseCase->>Repository: perform operation
Repository->>Pino: log operation metadata
Pino->>OpenTelemetry: correlate trace and span context
OpenTelemetry-->>Pino: export structured record
Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ast-grep (0.45.0)graphify-out/graph.htmlast-grep timed out on this file Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 19
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/config/enviroment_config.ts (1)
46-76: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
LOG_LEVELvalue is never validated, and the union type is silently widened tostring.
verifyMandatoryEnvonly asserts presence, soLOG_LEVEL=verbosepasses and is handed to pino, which throws on an unknown level at startup. DeclaringlogLevel: stringonEnviromentalso discards the union you added onEnvVar.🛡️ Validate the value and preserve the narrow type
+const LOG_LEVELS = [ + 'trace', + 'debug', + 'info', + 'warn', + 'error', + 'fatal', +] as const +export type LogLevel = (typeof LOG_LEVELS)[number]app: { ... - logLevel: string + logLevel: LogLevel }- logLevel: process.env.LOG_LEVEL, + logLevel: LOG_LEVELS.includes(process.env.LOG_LEVEL as LogLevel) + ? (process.env.LOG_LEVEL as LogLevel) + : 'info',🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/config/enviroment_config.ts` around lines 46 - 76, Update getEnv and the Enviroment type so LOG_LEVEL is validated against the supported log-level values before constructing the configuration, rejecting values such as “verbose” with the existing environment validation error path. Preserve the narrow log-level union from EnvVar instead of declaring Enviroment.logLevel as string, and ensure the returned process.env.LOG_LEVEL value is typed accordingly.
🧹 Nitpick comments (6)
src/config/logger.ts (1)
6-6: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
getEnv()is invoked twice and the fallback is now unreachable.
LOG_LEVELis mandatory inenviroment_config.ts, sogetEnv()either throws or returns a truthylogLevel— theproduction ? 'info' : 'debug'branch is dead. Resolve the env once.♻️ Suggested cleanup
-export const logger = pino({ - level: getEnv().app.logLevel || (getEnv().app.enviroment === 'production' ? 'info' : 'debug'), +const env = getEnv() + +export const logger = pino({ + level: env.app.logLevel,🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/config/logger.ts` at line 6, Update the logger configuration’s level expression to resolve getEnv() once and reuse the resulting environment object, removing the unreachable production/development fallback while preserving the mandatory logLevel value.src/core/providers/mfa.repository.ts (1)
36-36: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueLog message doesn't match the statement it precedes.
The immediate query is a duplicate-check
select; the insert happens later at line 58 and may never run (theMFA_ALREADY_EXISTthrow). Consider'Database query: check existing MFA strategy'here, and, if useful, a separate debug line at the actual insert.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/core/providers/mfa.repository.ts` at line 36, Update the debug log in the strategy-creation flow to describe the preceding duplicate-check select, using wording such as “check existing MFA strategy” instead of “insert MFA strategy.” If retaining insert-specific logging, add a separate message immediately before the actual insert operation, after the MFA_ALREADY_EXIST check.specs/001-add-flow-logging/research.md (1)
21-29: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueTwo performance claims here are inaccurate.
fast-redactis fast but not zero-cost, and Pino writes to stdout synchronously by default — there is no "asynchronous batching to Uptrace" unless a transport/worker is configured. Since SC-003 (≤5% latency overhead) rests on these assumptions, consider softening the wording or documenting the transport that actually provides async delivery.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@specs/001-add-flow-logging/research.md` around lines 21 - 29, Correct the inaccurate performance claims in the research document: remove the assertion that fast redaction has zero runtime cost, and qualify asynchronous Pino delivery by documenting the configured transport/worker or stating that stdout is synchronous by default. Also revise the related SC-003 rationale so the latency target is not based on unsupported assumptions.coverage/lcov.info (1)
660-847: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDon't commit the LCOV artifact that overrides
.gitignore.
coverage/*and*.lcovare already ignored, but.gitignoreexplicitly reallows onlycoverage/lcov.info, so this generated file is tracked and can create large unreviewable coverage churn. If coverage is useful, ignorecoverage/entirely and upload the LCOV artifact in CI / send it to Sonar instead.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@coverage/lcov.info` around lines 660 - 847, The generated coverage/lcov.info artifact must not be committed. Remove it from version control and update the ignore configuration to ignore the coverage directory without explicitly reallowing coverage/lcov.info; preserve CI/Sonar handling for uploading coverage artifacts if needed.graphify-out/graph.html (1)
1-320: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider excluding generated Graphify visualization artifacts from version control.
This entire file is machine-generated output (embedded
RAW_NODES/RAW_EDGES/LEGENDdata plus rendering script) rather than authored code. Committing large generated HTML/JS artifacts like this bloats the repository and diverges on every regeneration, complicating diffs and reviews.Consider adding
graphify-out/to.gitignoreand instead generating/publishing this report as a CI artifact if it needs to be shared.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@graphify-out/graph.html` around lines 1 - 320, Exclude the machine-generated Graphify output directory from version control by adding graphify-out/ to the repository’s .gitignore. Leave the generated graph.html artifact unchanged and rely on CI artifact publishing or regeneration when the visualization needs to be shared.graphify-out/graph.json (1)
1-32267: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winGenerated Graphify artifact committed to the repo — consider excluding from version control.
This entire 32K+ line file is auto-generated code-graph output (
_origin: "ast", confidence scores, and abuilt_at_commithash pinning it to a specific commit). Committing regenerable, commit-pinned analysis artifacts of this size causes repository bloat, noisy diffs on every regeneration, and immediate staleness relative to the current commit.Unless there's a deliberate goal to keep historical graph snapshots in-repo, consider adding
graphify-out/to.gitignoreand instead publishing this as a CI build artifact or storing it out-of-repo (e.g., artifact storage, a docs site, or a dedicated branch).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@graphify-out/graph.json` around lines 1 - 32267, Remove the generated graphify-out artifact from version control and add graphify-out/ to the repository ignore configuration. Preserve any source or generation workflow needed to recreate graph.json, but do not commit this regenerable, commit-pinned output unless historical snapshots are explicitly required.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.specify/memory/constitution.md:
- Line 12: Update the external-services listing in the constitution to replace
the stale “Redis” reference with “Valkey,” or explicitly identify Redis as a
compatibility alias, so it matches the later Valkey cache terminology and
adapter contract.
- Around line 14-15: Unify observability documentation with the runtime’s
selected Pino logger and SigNoz/OTLP exporter. In
.specify/memory/constitution.md lines 14-15, replace the Winston/Uptrace
references; update the Monitoring section at lines 40-42 to name SigNoz; and
revise specs/001-add-flow-logging/plan.md line 9 to remove Uptrace and
consistently reference SigNoz.
In `@graphify-out/.graphify_python`:
- Line 1: Remove machine-local metadata from all listed generated artifacts:
replace or omit the interpreter pointer in graphify-out/.graphify_python;
regenerate the AST cache files at
graphify-out/cache/ast/v0.9.29/a412e829419ad03c761ab7f88fa02dc8bf6a01ce9f40869eafb6c76fe85a5bfa.json,
a9c6383a1eb7ba23b6925a62eae5635e63c836d61b2878ebfc3b28c3f47af35e.json,
ab8e59fa8724ca438acb8add08e834d9cfa0fa1a34f92f7545fddaa27da23343.json,
ae22b7c7ecb6ccd516fed25916e465146432c58f1bef904a92b535ac0bbecfcf.json,
b314d97a20868c731da275a5a30d3a2860e2fb21226f6eee249d500861544ce6.json, and
bd00ea412c1a2894a519eec2bf0067d1150cdd267f1099debc4536f4a5d0f20a.json with IDs
derived from relative paths; and clean
a571e6de0ed5f7e161a81def91f91043506dbf562ac3be4cfa3f4c48c49683ec.json of
absolute IDs, file URLs, and target paths.
In
`@graphify-out/cache/ast/v0.9.29/070ed0dfafd8310a243b51cc30b1b6dfb19883fdd5ad20e4b53e45eb7f939e3e.json`:
- Line 1: Normalize machine-specific absolute workspace paths in the generated
Graphify caches. In
graphify-out/cache/ast/v0.9.29/070ed0dfafd8310a243b51cc30b1b6dfb19883fdd5ad20e4b53e45eb7f939e3e.json:1-1,
07e40705140f96139361d29ad46bce8cdb8303339171f45cb1436780d4da58f3.json:1-1, and
08e79622b777468d92f233b7c30b8ed76c9c48ad03597affb7c92c1d49dc681b.json:1-1,
regenerate node IDs using repository-relative paths; in
graphify-out/cache/ast/v0.9.29/107c774c59ce86f256e108b38364b6606584460b17d44294abbbc3de5da6a2a2.json:1-1,
replace the absolute target_file value with its repository-relative path.
In
`@graphify-out/cache/ast/v0.9.29/14bf6d184a95615ed9707b47442e5f55b685e9b0121c61164f5998a799018900.json`:
- Line 1: Sanitize generated Graphify artifacts so host-specific absolute
checkout paths are never persisted. In
graphify-out/cache/ast/v0.9.29/14bf6d184a95615ed9707b47442e5f55b685e9b0121c61164f5998a799018900.json#L1,
normalize package graph node IDs; apply the same node-ID normalization to
graphify-out/cache/ast/v0.9.29/23a03f849ef54c3f2b89d56f47bc3851236f539e325de0897b699b57dae7be74.json#L1,
graphify-out/cache/ast/v0.9.29/2734a509d4b2f34ee6258475c4fb2e80a6dbfcbc47c8552df5b6278907529250.json#L1,
graphify-out/cache/ast/v0.9.29/2ae70ccc099030710c9a9e142ae83c454ca9f2526d2c0ef94ca42709e5b3342d.json#L1,
graphify-out/cache/ast/v0.9.29/327b9177caee62513cec0e53459a6ac09f569636f9648e8d77834fba89ad6bfd.json#L1,
graphify-out/cache/ast/v0.9.29/3c525c42b7d7f51cc46c1ee2a56c266665067b217ecaf76b5bf03775a9b29c4f.json#L1,
graphify-out/cache/ast/v0.9.29/64bbd0b8aadc612d601eb49036e7574d6546fe9edc0db0156cb303d1b7ab0ef6.json#L1,
graphify-out/cache/ast/v0.9.29/7aefc125bffb446ba63881ed739ddeaacd7402e025fe0782c4b214bb56ca583f.json#L1,
and
graphify-out/cache/ast/v0.9.29/9bd6e6dd116b6b29717310b09e26cfd30acdc302612d8f29f2355d2e7ea476c2.json#L1;
additionally remove the absolute target_file from
graphify-out/cache/ast/v0.9.29/521bc5c14198bf8f85b2f10cf839fc26cb617b8f4a3510401189402aa041e9b9.json#L1
and normalize its node IDs.
In
`@graphify-out/cache/ast/v0.9.29/ca57f68b4280e2fc7dbb48a603a0c4582074460be6ab966f795f4b759013cf4f.json`:
- Line 1: Normalize the AST cache artifact to remove the machine-specific
“/home/andrew/Documents/...” prefix from all node IDs, source_file, target_file,
and related metadata fields. Update the create-new-feature.sh and its symbols
get_highest_from_specs(), clean_branch_name(), and generate_branch_name() to use
repository-relative paths and stable identifiers consistently before committing
the artifact.
In
`@graphify-out/cache/ast/v0.9.29/e7be3b18f45fb4e6fde36ba5f053eb4f1fb5897b61b53b2ef4069c93e8e2e145.json`:
- Line 1: Regenerate the AST cache artifact for the setup-plan.sh entry so node
IDs and target_file metadata no longer contain the machine-specific
“/home/andrew/Documents/...” prefix. Use repository-relative paths and stable
normalized identifiers consistently while preserving the existing node, edge,
and call relationships.
In `@graphify-out/cache/stat-index.json`:
- Line 1: Regenerate the cached stat index so the nested hashes map under the
top-level README.md entry uses the exact case-sensitive key README.md instead of
readme.md, preserving the actual filename casing for cache lookups.
In `@README.md`:
- Around line 57-58: Update the Docker prerequisites section in README.md to
describe the Docker Engine and Docker Compose plugin versions required by the
local scripts’ docker compose command, rather than listing a Docker Desktop
version alongside Compose. Remove the Docker Desktop-specific pin if the
supported Engine/plugin versions cannot be stated.
In `@specs/001-add-flow-logging/data-model.md`:
- Around line 14-15: Update the data model definitions for trace_id and span_id
to mark both fields optional, matching the {} result returned by logger.ts’s
mixin() when trace.getActiveSpan() is absent. Do not require an active span or
treat these fields as universally present.
In `@specs/001-add-flow-logging/plan.md`:
- Around line 68-99: Replace the developer-local file:/// links in the plan’s
MODIFY entries with repository-relative links, such as
../../src/config/logger.ts, using the correct relative path for each referenced
file. Preserve the listed files and descriptions unchanged.
- Line 17: Update the **Storage** deployment assumption in the plan to remove
the claim that ClickHouse and PostgreSQL are provided by Uptrace Docker
services. Describe the actual required deployment prerequisites based on the
current stack context, including only services that must be provisioned
externally or separately.
- Line 35: Update the “Hexagonal Architecture Compliance” plan section to remove
direct concrete logger usage from core use cases and repositories. Define and
inject an abstract logging port into core components, or confine Pino and
src/config/logger.ts usage to presentation/infrastructure adapters, while
preserving logging behavior without core dependencies on configuration or
framework code.
In `@specs/001-add-flow-logging/quickstart.md`:
- Around line 10-30: Update the quickstart steps around the docker compose
startup and Uptrace verification to match the services retained by
docker-compose.yml. Remove the ClickHouse/Uptrace startup and localhost:14318 UI
assumptions, and rewrite Step 3 to verify flow logs through application stdout
as described by tasks.md T-003/Phase 3.
In `@src/config/enviroment_config.ts`:
- Line 33: Update the environment configuration around mandatoryKeys so
LOG_LEVEL remains optional and is not fetched through getEnv() during module
initialization. Derive the logger level directly from process.env.LOG_LEVEL,
validate it using the existing logger-level handling, and apply a sensible
default when it is absent.
In `@src/config/logger.ts`:
- Around line 41-48: Update maskEmail to split the address at the last '@'
rather than destructuring email.split('@'), preserving the entire
domain—including any additional '@' characters—in the masked output while
keeping the existing local-part masking behavior.
- Around line 7-26: Extend the redact.paths configuration in the logger setup to
cover sensitive fields at the deeper nesting levels used by payloads, including
paths such as user.info.password and equivalent password, confirmPassword, code,
token, and secret variants. Preserve the existing top-level and one-level
wildcard entries and the current censor value.
In `@src/core/providers/mfa.repository.ts`:
- Around line 46-48: Remove the empty GA phone-check branch in the MFA
repository, including its note, unless implementing the intended validation is
required by surrounding logic. Preserve the existing strategy handling and
ensure no dead empty conditional remains.
In `@src/core/providers/token.repository.ts`:
- Around line 15-20: Update the debug logging in the token cache invalidation
and token creation methods so completion messages are emitted only after
cache.set and token signing succeed, or rename the pre-operation messages to
indicate they started. Ensure failures do not produce logs claiming successful
completion, using the relevant invalidation method and create method.
---
Outside diff comments:
In `@src/config/enviroment_config.ts`:
- Around line 46-76: Update getEnv and the Enviroment type so LOG_LEVEL is
validated against the supported log-level values before constructing the
configuration, rejecting values such as “verbose” with the existing environment
validation error path. Preserve the narrow log-level union from EnvVar instead
of declaring Enviroment.logLevel as string, and ensure the returned
process.env.LOG_LEVEL value is typed accordingly.
---
Nitpick comments:
In `@coverage/lcov.info`:
- Around line 660-847: The generated coverage/lcov.info artifact must not be
committed. Remove it from version control and update the ignore configuration to
ignore the coverage directory without explicitly reallowing coverage/lcov.info;
preserve CI/Sonar handling for uploading coverage artifacts if needed.
In `@graphify-out/graph.html`:
- Around line 1-320: Exclude the machine-generated Graphify output directory
from version control by adding graphify-out/ to the repository’s .gitignore.
Leave the generated graph.html artifact unchanged and rely on CI artifact
publishing or regeneration when the visualization needs to be shared.
In `@graphify-out/graph.json`:
- Around line 1-32267: Remove the generated graphify-out artifact from version
control and add graphify-out/ to the repository ignore configuration. Preserve
any source or generation workflow needed to recreate graph.json, but do not
commit this regenerable, commit-pinned output unless historical snapshots are
explicitly required.
In `@specs/001-add-flow-logging/research.md`:
- Around line 21-29: Correct the inaccurate performance claims in the research
document: remove the assertion that fast redaction has zero runtime cost, and
qualify asynchronous Pino delivery by documenting the configured
transport/worker or stating that stdout is synchronous by default. Also revise
the related SC-003 rationale so the latency target is not based on unsupported
assumptions.
In `@src/config/logger.ts`:
- Line 6: Update the logger configuration’s level expression to resolve getEnv()
once and reuse the resulting environment object, removing the unreachable
production/development fallback while preserving the mandatory logLevel value.
In `@src/core/providers/mfa.repository.ts`:
- Line 36: Update the debug log in the strategy-creation flow to describe the
preceding duplicate-check select, using wording such as “check existing MFA
strategy” instead of “insert MFA strategy.” If retaining insert-specific
logging, add a separate message immediately before the actual insert operation,
after the MFA_ALREADY_EXIST check.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: a348fc2c-e8bd-47f5-a25f-4059cce5007e
📒 Files selected for processing (75)
.specify/feature.json.specify/init-options.json.specify/integration.json.specify/integrations/agy.manifest.json.specify/integrations/speckit.manifest.json.specify/memory/constitution.md.specify/workflows/speckit/workflow.ymlREADME.mdcoverage/lcov.infodocker-compose.ymlgraphify-out/.graphify_labels.jsongraphify-out/.graphify_labels.json.siggraphify-out/.graphify_pythongraphify-out/.graphify_rootgraphify-out/2026-07-29/.graphify_labels.jsongraphify-out/2026-07-29/GRAPH_REPORT.mdgraphify-out/2026-07-29/cost.jsongraphify-out/2026-07-29/graph.jsongraphify-out/2026-07-29/manifest.jsongraphify-out/GRAPH_REPORT.mdgraphify-out/cache/ast/v0.9.29/070ed0dfafd8310a243b51cc30b1b6dfb19883fdd5ad20e4b53e45eb7f939e3e.jsongraphify-out/cache/ast/v0.9.29/07e40705140f96139361d29ad46bce8cdb8303339171f45cb1436780d4da58f3.jsongraphify-out/cache/ast/v0.9.29/08e79622b777468d92f233b7c30b8ed76c9c48ad03597affb7c92c1d49dc681b.jsongraphify-out/cache/ast/v0.9.29/107c774c59ce86f256e108b38364b6606584460b17d44294abbbc3de5da6a2a2.jsongraphify-out/cache/ast/v0.9.29/124ca6da475ca52c2294b4e25494fd5851c67da3be60722f5e9b58421a2eb31f.jsongraphify-out/cache/ast/v0.9.29/14bf6d184a95615ed9707b47442e5f55b685e9b0121c61164f5998a799018900.jsongraphify-out/cache/ast/v0.9.29/23a03f849ef54c3f2b89d56f47bc3851236f539e325de0897b699b57dae7be74.jsongraphify-out/cache/ast/v0.9.29/2734a509d4b2f34ee6258475c4fb2e80a6dbfcbc47c8552df5b6278907529250.jsongraphify-out/cache/ast/v0.9.29/2ae70ccc099030710c9a9e142ae83c454ca9f2526d2c0ef94ca42709e5b3342d.jsongraphify-out/cache/ast/v0.9.29/327b9177caee62513cec0e53459a6ac09f569636f9648e8d77834fba89ad6bfd.jsongraphify-out/cache/ast/v0.9.29/3c525c42b7d7f51cc46c1ee2a56c266665067b217ecaf76b5bf03775a9b29c4f.jsongraphify-out/cache/ast/v0.9.29/521bc5c14198bf8f85b2f10cf839fc26cb617b8f4a3510401189402aa041e9b9.jsongraphify-out/cache/ast/v0.9.29/64bbd0b8aadc612d601eb49036e7574d6546fe9edc0db0156cb303d1b7ab0ef6.jsongraphify-out/cache/ast/v0.9.29/7aefc125bffb446ba63881ed739ddeaacd7402e025fe0782c4b214bb56ca583f.jsongraphify-out/cache/ast/v0.9.29/9bd6e6dd116b6b29717310b09e26cfd30acdc302612d8f29f2355d2e7ea476c2.jsongraphify-out/cache/ast/v0.9.29/a412e829419ad03c761ab7f88fa02dc8bf6a01ce9f40869eafb6c76fe85a5bfa.jsongraphify-out/cache/ast/v0.9.29/a571e6de0ed5f7e161a81def91f91043506dbf562ac3be4cfa3f4c48c49683ec.jsongraphify-out/cache/ast/v0.9.29/a9c6383a1eb7ba23b6925a62eae5635e63c836d61b2878ebfc3b28c3f47af35e.jsongraphify-out/cache/ast/v0.9.29/ab8e59fa8724ca438acb8add08e834d9cfa0fa1a34f92f7545fddaa27da23343.jsongraphify-out/cache/ast/v0.9.29/ae22b7c7ecb6ccd516fed25916e465146432c58f1bef904a92b535ac0bbecfcf.jsongraphify-out/cache/ast/v0.9.29/b314d97a20868c731da275a5a30d3a2860e2fb21226f6eee249d500861544ce6.jsongraphify-out/cache/ast/v0.9.29/bd00ea412c1a2894a519eec2bf0067d1150cdd267f1099debc4536f4a5d0f20a.jsongraphify-out/cache/ast/v0.9.29/ca57f68b4280e2fc7dbb48a603a0c4582074460be6ab966f795f4b759013cf4f.jsongraphify-out/cache/ast/v0.9.29/e7be3b18f45fb4e6fde36ba5f053eb4f1fb5897b61b53b2ef4069c93e8e2e145.jsongraphify-out/cache/ast/v0.9.29/ea41c268b9da009a1d55e9da540c89dbf583c8c67fe780ad2b11e9e1f7853154.jsongraphify-out/cache/ast/v0.9.29/fc699f9aa32f5f8d8a9b9f564a50442d1c127d16804f7793cd9c343fb29c2ab8.jsongraphify-out/cache/last_query_stampgraphify-out/cache/stat-index.jsongraphify-out/cost.jsongraphify-out/graph.htmlgraphify-out/graph.jsongraphify-out/manifest.jsonotel-collector.yamlspecs/001-add-flow-logging/checklists/requirements.mdspecs/001-add-flow-logging/data-model.mdspecs/001-add-flow-logging/plan.mdspecs/001-add-flow-logging/quickstart.mdspecs/001-add-flow-logging/research.mdspecs/001-add-flow-logging/spec.mdspecs/001-add-flow-logging/tasks.mdsrc/config/enviroment_config.tssrc/config/logger.tssrc/core/providers/mfa.repository.tssrc/core/providers/token.repository.tssrc/core/providers/user.repository.tssrc/core/usecases/login.usecase.tssrc/core/usecases/logout.usecase.tssrc/core/usecases/mfa.usecase.tssrc/core/usecases/mfa_choose.usecase.tssrc/core/usecases/mfa_code.usecase.tssrc/core/usecases/organization.usecase.tssrc/core/usecases/reset_password.usecase.tssrc/core/usecases/user.usecase.tssrc/presentation/http/server.tsuptrace.yml
💤 Files with no reviewable changes (3)
- uptrace.yml
- otel-collector.yaml
- docker-compose.yml
|
|
||
| ### III. Strict Token & Session Lifecycle | ||
| JWT-based session authentication must enforce a strict 1-hour expiration window, support token rotation/refresh mechanics, and utilize a Redis-backed cache blacklist for immediate token invalidation upon logout. | ||
| JWT-based session authentication must enforce a strict 1-hour expiration window, support token rotation/refresh mechanics, and utilize a Valkey-backed cache blacklist for immediate token invalidation upon logout. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== files =="
git ls-files | rg '(^|/)(constitution\.md|.*cache.*|.*redis.*|.*valkey.*|.*observability.*|.*signoz.*|.*pinecone.*|.*pino.*)$' || true
echo
echo "== constitution mentions =="
if [ -f .specify/memory/constitution.md ]; then
nl -ba .specify/memory/constitution.md | sed -n '1,220p'
fi
echo
echo "== runtime/config terms =="
rg -n --no-heading -i 'redis|valkey|cache|observability|signoz|pino|pinecone|token blacklist|logout' . --glob '!node_modules/**' --glob '!dist/**' --glob '!build/**' | head -n 200Repository: auth-plus/auth-plus-authentication
Length of output: 3008
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== constitution content =="
awk '{printf "%6d %s\n", NR, $0}' .specify/memory/constitution.md | sed -n '1,220p'
echo
echo "== relevant config file =="
awk '{printf "%6d %s\n", NR, $0}' src/core/config/cache.ts | sed -n '1,220p'
echo
echo "== cache terminology in tracked docs/config/src =="
awk '
tolower($0) ~ /redis|valkey|cache|token blacklist|logout|observability|signoz|pino|pinecone/ {
printf "%s: ", FILENAME
printf "%6d ", NR
print $0
}
' .specify/memory/constitution.md src/core/config/cache.ts 2>/dev/null
echo
echo "== exact grep in tracked files =="
git grep -n -i 'redis\|valkey\|cache blacklist\|observability\|signoz\|pino\|pinecone' -- .specify src || trueRepository: auth-plus/auth-plus-authentication
Length of output: 15962
Keep the cache terminology consistent.
Line 6 still lists Redis among external services, while later rules and the cache config use Valkey, making the adapter contract misleading. Update the stale Redis reference or mark it as a compatibility alias.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.specify/memory/constitution.md at line 12, Update the external-services
listing in the constitution to replace the stale “Redis” reference with
“Valkey,” or explicitly identify Redis as a compatibility alias, so it matches
the later Valkey cache terminology and adapter contract.
| ### IV. Deep Observability & Telemetry | ||
| All API endpoints, database queries, cache hits/misses, and messaging events MUST be instrumented using OpenTelemetry. Standardized logging (via Winston) and trace spans must be exported to a SigNoz collector to maintain continuous operational visibility. | ||
| All API endpoints, database queries, cache hits/misses, and messaging events MUST be instrumented using OpenTelemetry. Standardized logging (via Winston) and trace spans must be exported to an Uptrace collector to maintain continuous operational visibility. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== candidate files =="
git ls-files | rg '(^|/)(constitution\.md|plan\.md|.*signoz.*|.*opentelemetry.*|.*logging.*|.*telemetry.*|winston|pino|uptrace)' || true
echo
echo "== constitution snippet =="
if [ -f .specify/memory/constitution.md ]; then
nl -ba .specify/memory/constitution.md | sed -n '1,70p'
fi
echo
echo "== plan snippet =="
if [ -f specs/001-add-flow-logging/plan.md ]; then
nl -ba specs/001-add-flow-logging/plan.md | sed -n '1,80p'
fi
echo
echo "== observability-related string search =="
rg -n -i 'win(ston)?|uptrace|signoz|pino|opentelemetry|tracer|metrics|logs|trace' .specify memory specs --glob '!node_modules' --glob '!dist' --glob '!build' || true
echo
echo "== logging/tracing config references =="
rg -n -i 'logger|winston|pino|opentelemetry|`@opentelemetry`|jaeger|zipkin|signoz|uptrace|fast-redact|signoz-collector|collector|otel' -g '!node_modules' -g '!dist' -g '!build' --glob '!*.lock' --glob '!*.md' .Repository: auth-plus/auth-plus-authentication
Length of output: 576
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== file sizes =="
wc -l .specify/memory/constitution.md specs/001-add-flow-logging/plan.md 2>/dev/null || true
echo
echo "== constitution excerpt =="
awk '{printf "%6d %s\n", NR, $0}' .specify/memory/constitution.md | sed -n '1,80p'
echo
echo "== plan excerpt =="
awk '{printf "%6d %s\n", NR, $0}' specs/001-add-flow-logging/plan.md | sed -n '1,100p'
echo
echo "== observability terms in tracked text/spec/config-like files =="
repo_obs_files=$(git ls-files | rg '(^|/)(constitution\.md|plan\.md|requirements\.md|spec\.md|research\.md|tasks\.md|data-model\.md|quickstart\.md|checklists/requirements\.md|.*log.*|.*trace.*|.*telemetry.*|.*observ.*|.*signoz.*|.*uptrace.*|package\.json|lockfile\.yaml|package-lock\.json|pnpm-lock\.yaml|yarn\.lock)$' || true)
echo "$repo_obs_files" | while IFS= read -r f; do
[ -z "$f" ] && continue
if rg -q -i 'win(ston)?|uptrace|signoz|pino|opentelemetry|tracer|metrics|logs|trace' "$f"; then
echo "--- $f"
rg -n -i 'win(ston)?|uptrace|signoz|pino|opentelemetry|tracer|metrics|logs|trace' "$f" || true
fi
done
echo
echo "== broader config/code references (non-md tracked) =="
rg -n -i 'logger|winston|pino|opentelemetry|`@opentelemetry`|jaeger|zipkin|signoz|uptrace|fast-redact|signoz-collector|collector|otel' --glob '!*node_modules/*' --glob '!*dist/*' --glob '!*build/*' --glob '!*.lock' --glob '!*.git/*' .Repository: auth-plus/auth-plus-authentication
Length of output: 50391
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== exact snippets =="
awk '{printf "%6d %s\n", NR, $0}' .specify/memory/constitution.md | sed -n '10,18p'
awk '{printf "%6d %s\n", NR, $0}' .specify/memory/constitution.md | sed -n '36,44p'
awk '{printf "%6d %s\n", NR, $0}' specs/001-add-flow-logging/plan.md | sed -n '6,12p'
echo
echo "== targeted observability dependency/config terms =="
python3 - <<'PY'
import json, pathlib, re
paths=[p for p in pathlib.Path('.').rglob('*') if p.is_file() and not any(part in {'.git','node_modules','dist','build','cache','graphify-out'} for part in p.parts)]
terms={
"winston": re.compile(r'\bwinston\b|`@opentelemetry/instrumentation-winston`|`@opentelemetry/winston-transport`', re.I),
"pino": re.compile(r'\bpino\b|`@opentelemetry/instrumentation-pino`|pino-http', re.I),
"uptrace": re.compile(r'\buptrace\b', re.I),
"signoz": re.compile(r'\bsignoz\b', re.I),
"otel": re.compile(r'`@opentelemetry`|exporter-(logs|metrics|trace)-otlp|sdk-node|tracerProvider|resourceDetectors', re.I),
}
for p in sorted(paths):
try: text= p.read_text(errors='ignore')
except Exception: continue
if '{' not in text[:1024] and 'Winston' not in text and 'Uptrace' not in text and 'SigNoz' not in text and '`@opentelemetry`' not in text:
continue
print(f'--- {p}')
for k,v in terms.items():
for m in v.finditer(text):
line=text[:m.start()].count('\n')+1
print(f' {k}:{line}:{m.group(0)}')
echo
echo "== package.json relevant dependencies =="
if [ -f package.json ]; then
python3 - <<'PY'
import json
data=json.load(open('package.json'))
vals=data.get('dependencies',{})|data.get('devDependencies',{})
for k,v in sorted(vals.items()):
if any(x in k.lower() for x in ['opentelemetry','winston','pino','uptrace','signoz','pino-http','winston']):
print(f'{k}: {v}')
PY
fiRepository: auth-plus/auth-plus-authentication
Length of output: 2334
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== targeted observability dependency/config terms =="
python3 - <<'PY'
import json, pathlib, re
paths=[p for p in pathlib.Path('.').rglob('*') if p.is_file() and not any(part in {'.git','node_modules','dist','build','cache','graphify-out'} for part in p.parts)]
terms={
"winston": re.compile(r'\bwinston\b|`@opentelemetry/instrumentation-winston`|`@opentelemetry/winston-transport`|winston-transport', re.I),
"pino": re.compile(r'\bpino\b|`@opentelemetry/instrumentation-pino`|pino-http\b', re.I),
"uptrace": re.compile(r'\buptrace\b', re.I),
"signoz": re.compile(r'\bsignoz\b', re.I),
"otel": re.compile(r'`@opentelemetry`|exporter-(logs|metrics|trace)-otlp|sdk-node|sdk-trace-base|tracerProvider|resourceDetectors', re.I),
}
for p in sorted(paths):
try: text= p.read_text(errors='ignore')
except Exception: continue
if not any(v.search(text) for v in terms.values()):
continue
hits=[]
for k,v in terms.items():
for m in v.finditer(text):
line=text[:m.start()].count('\n')+1
hits.append((line,k,m.group(0)))
print(f'--- {p}')
for line,k,term in hits:
print(f' {k}:{line}:{term}')
PY
echo
echo "== package.json relevant dependencies =="
if [ -f package.json ]; then
python3 - <<'PY'
import json
data=json.load(open('package.json'))
vals=data.get('dependencies',{})|data.get('devDependencies',{})
for k,v in sorted(vals.items()):
if any(x in k.lower() for x in ['opentelemetry','winston','pino','uptrace','signoz','pino-http','winston']):
print(f'{k}: {v}')
PY
fi
echo
echo "== tracked source/config files mentioning signoz/uptrace =="
rg -n -i 'signoz|uptrace|pinot' --glob '!node_modules' --glob '!dist' --glob '!build' --glob '!*.lock' --glob '!*.json' --glob '!*.md' . || trueRepository: auth-plus/auth-plus-authentication
Length of output: 50391
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== exact snippets =="
awk '{printf "%6d %s\n", NR, $0}' .specify/memory/constitution.md | sed -n '10,18p;36,44p'
awk '{printf "%6d %s\n", NR, $0}' specs/001-add-flow-logging/plan.md | sed -n '6,12p'
echo
echo "== package.json relevant dependencies =="
if [ -f package.json ]; then
python3 - <<'PY'
import json
data=json.load(open('package.json'))
deps=data.get('dependencies',{})|data.get('devDependencies',{})
for k in sorted(deps):
if any(x in k.lower() for x in ['opentelemetry','winston','pino','uptrace','signoz','pino-http','winston']):
print(f'{k}: {deps[k]}')
PY
fi
echo
echo "== focused observability terms in source/config/package files only =="
python3 - <<'PY'
import json, pathlib, re, subprocess
ignore = {'.git','node_modules','dist','build','cache','graphify-out'}
files = subprocess.check_output(['git','ls-files']).decode().splitlines()
terms = {
"winston": re.compile(r'\bwinston\b|`@opentelemetry/instrumentation-winston`|`@opentelemetry/winston-transport`|winston-transport', re.I),
"pino": re.compile(mobile r'\bpino\b|`@opentelemetry/instrumentation-pino`|pino-http\b', re.I),
"signoz": re.compile(r'\bsignoz\b', re.I),
"uptrace": re.compile(r'\buptrace\b', re.I),
}
for p in files:
if any(part in ignore for part in p.split('/')):
continue
ext = pathlib.Path(p).suffix.lower()
if p == 'package.json' or ext in {'.ts','.js','.mts','.mjs','.json','.yml','.yaml','.env*'}:
try:
text = pathlib.Path(p).read_text(errors='ignore')
except Exception:
continue
for k,v in terms.items():
for m in v.finditer(text):
line = text[:m.start()].count('\n')+1
print(f'{p}:{line}:{k}:{m.group(0)}')
PY
echo
echo "== focused signoz/uptrace occurrences among tracked files =="
rg -n -i '\bsignoz\b|\buptrace\b|\bpino\b|\bwinston\b' --glob '!node_modules' --glob '!dist' --glob '!build' --glob '!cache' --glob '!graphify-out' . | head -n 200 || trueRepository: auth-plus/auth-plus-authentication
Length of output: 3240
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== focused observability terms in tracked non-output files =="
python3 - <<'PY'
import pathlib
import re
terms = {
"winston": re.compile(r'\bwinston\b|`@opentelemetry/instrumentation-winston`|`@opentelemetry/winston-transport`|winston-transport', re.I),
"pino": re.compile(r'\bpino\b|`@opentelemetry/instrumentation-pino`|pino-http\b', re.I),
"signoz": re.compile(r'\bsignoz\b', re.I),
"uptrace": re.compile(r'\buptrace\b', re.I),
}
for p in pathlib.Path('.').rglob('*'):
if not p.is_file():
continue
bad = {'.git','node_modules','dist','build','cache','graphify-out'}
if any(part in bad for part in p.parts):
continue
rel = str(p)
ext = p.suffix.lower()
if rel == 'package.json' or ext in {'.ts','.js','.mts','.mjs','.json','.yml','.yaml'}:
try:
text = p.read_text(errors='ignore')
except Exception:
continue
for k, pattern in terms.items():
for m in pattern.finditer(text):
line = text[:m.start()].count('\n') + 1
print(f'{rel}:{line}:{k}:{m.group(0)}')
PYRepository: auth-plus/auth-plus-authentication
Length of output: 3279
Unify the observability stack references.
The dependencies include both Pino and Winston packages, but the runtime wiring uses Pino and a SigNoz/Otlp export target, while the requirements still promise Winston and/or Uptrace. Pick the intended logger/exporter and update the affected docs.
.specify/memory/constitution.md#L15: remove Winston/Uptrace or make the runtime match it..specify/memory/constitution.md#L42: adjustMonitoringto the selected exporter.specs/001-add-flow-logging/plan.md#L9: keep Uptrace only if that is the selected destination; otherwise revise to SigNoz.
📍 Affects 2 files
.specify/memory/constitution.md#L14-L15(this comment).specify/memory/constitution.md#L40-L42specs/001-add-flow-logging/plan.md#L9-L9
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.specify/memory/constitution.md around lines 14 - 15, Unify observability
documentation with the runtime’s selected Pino logger and SigNoz/OTLP exporter.
In .specify/memory/constitution.md lines 14-15, replace the Winston/Uptrace
references; update the Monitoring section at lines 40-42 to name SigNoz; and
revise specs/001-add-flow-logging/plan.md line 9 to remove Uptrace and
consistently reference SigNoz.
| @@ -0,0 +1 @@ | |||
| /home/andrew/.local/share/uv/tools/graphifyy/bin/python No newline at end of file | |||
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
Remove machine-local Graphify metadata from committed artifacts.
The interpreter pointer and AST cache IDs embed /home/andrew/...; one artifact also contains file:///home/andrew/... URLs. This leaks local filesystem information and makes the generated output non-reproducible across checkouts.
graphify-out/.graphify_python#L1-L1: replace the absolute interpreter path with portable metadata or omit the file.graphify-out/cache/ast/v0.9.29/a412e829419ad03c761ab7f88fa02dc8bf6a01ce9f40869eafb6c76fe85a5bfa.json#L1-L1: generate IDs from relative paths.graphify-out/cache/ast/v0.9.29/a571e6de0ed5f7e161a81def91f91043506dbf562ac3be4cfa3f4c48c49683ec.json#L1-L1: remove absolute IDs, URLs, and target paths.graphify-out/cache/ast/v0.9.29/a9c6383a1eb7ba23b6925a62eae5635e63c836d61b2878ebfc3b28c3f47af35e.json#L1-L1: generate portable node IDs.graphify-out/cache/ast/v0.9.29/ab8e59fa8724ca438acb8add08e834d9cfa0fa1a34f92f7545fddaa27da23343.json#L1-L1: generate portable node IDs.graphify-out/cache/ast/v0.9.29/ae22b7c7ecb6ccd516fed25916e465146432c58f1bef904a92b535ac0bbecfcf.json#L1-L1: generate portable node IDs.graphify-out/cache/ast/v0.9.29/b314d97a20868c731da275a5a30d3a2860e2fb21226f6eee249d500861544ce6.json#L1-L1: generate portable node IDs.graphify-out/cache/ast/v0.9.29/bd00ea412c1a2894a519eec2bf0067d1150cdd267f1099debc4536f4a5d0f20a.json#L1-L1: generate portable node IDs.
📍 Affects 8 files
graphify-out/.graphify_python#L1-L1(this comment)graphify-out/cache/ast/v0.9.29/a412e829419ad03c761ab7f88fa02dc8bf6a01ce9f40869eafb6c76fe85a5bfa.json#L1-L1graphify-out/cache/ast/v0.9.29/a571e6de0ed5f7e161a81def91f91043506dbf562ac3be4cfa3f4c48c49683ec.json#L1-L1graphify-out/cache/ast/v0.9.29/a9c6383a1eb7ba23b6925a62eae5635e63c836d61b2878ebfc3b28c3f47af35e.json#L1-L1graphify-out/cache/ast/v0.9.29/ab8e59fa8724ca438acb8add08e834d9cfa0fa1a34f92f7545fddaa27da23343.json#L1-L1graphify-out/cache/ast/v0.9.29/ae22b7c7ecb6ccd516fed25916e465146432c58f1bef904a92b535ac0bbecfcf.json#L1-L1graphify-out/cache/ast/v0.9.29/b314d97a20868c731da275a5a30d3a2860e2fb21226f6eee249d500861544ce6.json#L1-L1graphify-out/cache/ast/v0.9.29/bd00ea412c1a2894a519eec2bf0067d1150cdd267f1099debc4536f4a5d0f20a.json#L1-L1
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@graphify-out/.graphify_python` at line 1, Remove machine-local metadata from
all listed generated artifacts: replace or omit the interpreter pointer in
graphify-out/.graphify_python; regenerate the AST cache files at
graphify-out/cache/ast/v0.9.29/a412e829419ad03c761ab7f88fa02dc8bf6a01ce9f40869eafb6c76fe85a5bfa.json,
a9c6383a1eb7ba23b6925a62eae5635e63c836d61b2878ebfc3b28c3f47af35e.json,
ab8e59fa8724ca438acb8add08e834d9cfa0fa1a34f92f7545fddaa27da23343.json,
ae22b7c7ecb6ccd516fed25916e465146432c58f1bef904a92b535ac0bbecfcf.json,
b314d97a20868c731da275a5a30d3a2860e2fb21226f6eee249d500861544ce6.json, and
bd00ea412c1a2894a519eec2bf0067d1150cdd267f1099debc4536f4a5d0f20a.json with IDs
derived from relative paths; and clean
a571e6de0ed5f7e161a81def91f91043506dbf562ac3be4cfa3f4c48c49683ec.json of
absolute IDs, file URLs, and target paths.
| @@ -0,0 +1 @@ | |||
| {"nodes": [{"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_md", "label": "tasks-template.md", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L1"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "label": "Tasks: [FEATURE NAME]", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L6"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_format_id_p_story_description", "label": "Format: `[ID] [P?] [Story] Description`", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L16"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_path_conventions", "label": "Path Conventions", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L22"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_1_setup_shared_infrastructure", "label": "Phase 1: Setup (Shared Infrastructure)", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L48"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_2_foundational_blocking_prerequisites", "label": "Phase 2: Foundational (Blocking Prerequisites)", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L58"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_3_user_story_1_title_priority_p1_mvp", "label": "Phase 3: User Story 1 - [Title] (Priority: P1) \ud83c\udfaf MVP", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L77"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tests_for_user_story_1_optional_only_if_tests_requested", "label": "Tests for User Story 1 (OPTIONAL - only if tests requested) \u26a0\ufe0f", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L83"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_for_user_story_1", "label": "Implementation for User Story 1", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L90"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_4_user_story_2_title_priority_p2", "label": "Phase 4: User Story 2 - [Title] (Priority: P2)", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L103"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tests_for_user_story_2_optional_only_if_tests_requested", "label": "Tests for User Story 2 (OPTIONAL - only if tests requested) \u26a0\ufe0f", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L109"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_for_user_story_2", "label": "Implementation for User Story 2", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L114"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_5_user_story_3_title_priority_p3", "label": "Phase 5: User Story 3 - [Title] (Priority: P3)", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L125"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tests_for_user_story_3_optional_only_if_tests_requested", "label": "Tests for User Story 3 (OPTIONAL - only if tests requested) \u26a0\ufe0f", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L131"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_for_user_story_3", "label": "Implementation for User Story 3", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L136"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_n_polish_cross_cutting_concerns", "label": "Phase N: Polish & Cross-Cutting Concerns", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L150"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_dependencies_execution_order", "label": "Dependencies & Execution Order", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L163"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_dependencies", "label": "Phase Dependencies", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L165"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_user_story_dependencies", "label": "User Story Dependencies", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L174"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_within_each_user_story", "label": "Within Each User Story", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L180"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_parallel_opportunities", "label": "Parallel Opportunities", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L188"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_parallel_example_user_story_1", "label": "Parallel Example: User Story 1", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L199"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_strategy", "label": "Implementation Strategy", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L213"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_mvp_first_user_story_1_only", "label": "MVP First (User Story 1 Only)", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L215"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_incremental_delivery", "label": "Incremental Delivery", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L223"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_parallel_team_strategy", "label": "Parallel Team Strategy", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L231"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_notes", "label": "Notes", "file_type": "document", "source_file": ".specify/templates/tasks-template.md", "source_location": "L244"}], "edges": [{"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_md", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L6", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_format_id_p_story_description", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L16", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_path_conventions", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L22", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_1_setup_shared_infrastructure", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L48", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_2_foundational_blocking_prerequisites", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L58", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_3_user_story_1_title_priority_p1_mvp", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L77", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_3_user_story_1_title_priority_p1_mvp", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tests_for_user_story_1_optional_only_if_tests_requested", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L83", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_3_user_story_1_title_priority_p1_mvp", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_for_user_story_1", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L90", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_4_user_story_2_title_priority_p2", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L103", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_4_user_story_2_title_priority_p2", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tests_for_user_story_2_optional_only_if_tests_requested", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L109", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_4_user_story_2_title_priority_p2", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_for_user_story_2", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L114", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_5_user_story_3_title_priority_p3", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L125", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_5_user_story_3_title_priority_p3", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tests_for_user_story_3_optional_only_if_tests_requested", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L131", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_5_user_story_3_title_priority_p3", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_for_user_story_3", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L136", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_n_polish_cross_cutting_concerns", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L150", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_dependencies_execution_order", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L163", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_dependencies_execution_order", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_phase_dependencies", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L165", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_dependencies_execution_order", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_user_story_dependencies", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L174", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_dependencies_execution_order", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_within_each_user_story", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L180", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_dependencies_execution_order", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_parallel_opportunities", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L188", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_parallel_example_user_story_1", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L199", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_strategy", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L213", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_strategy", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_mvp_first_user_story_1_only", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L215", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_strategy", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_incremental_delivery", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L223", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_implementation_strategy", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_parallel_team_strategy", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L231", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_tasks_feature_name", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_specify_templates_tasks_template_notes", "relation": "contains", "confidence": "EXTRACTED", "source_file": ".specify/templates/tasks-template.md", "source_location": "L244", "weight": 1.0}], "input_tokens": 0, "output_tokens": 0} No newline at end of file | |||
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
Normalize absolute paths across the generated Graphify caches.
These artifacts serialize /home/andrew/Documents/auth-plus-symphony/auth-plus-authentication, making graph references machine-specific and leaking local workspace details.
graphify-out/cache/ast/v0.9.29/070ed0dfafd8310a243b51cc30b1b6dfb19883fdd5ad20e4b53e45eb7f939e3e.json#L1-L1: generate repository-relative node IDs.graphify-out/cache/ast/v0.9.29/07e40705140f96139361d29ad46bce8cdb8303339171f45cb1436780d4da58f3.json#L1-L1: generate repository-relative node IDs.graphify-out/cache/ast/v0.9.29/08e79622b777468d92f233b7c30b8ed76c9c48ad03597affb7c92c1d49dc681b.json#L1-L1: generate repository-relative node IDs.graphify-out/cache/ast/v0.9.29/107c774c59ce86f256e108b38364b6606584460b17d44294abbbc3de5da6a2a2.json#L1-L1: replace the absolutetarget_filewith a repository-relative path.
📍 Affects 4 files
graphify-out/cache/ast/v0.9.29/070ed0dfafd8310a243b51cc30b1b6dfb19883fdd5ad20e4b53e45eb7f939e3e.json#L1-L1(this comment)graphify-out/cache/ast/v0.9.29/07e40705140f96139361d29ad46bce8cdb8303339171f45cb1436780d4da58f3.json#L1-L1graphify-out/cache/ast/v0.9.29/08e79622b777468d92f233b7c30b8ed76c9c48ad03597affb7c92c1d49dc681b.json#L1-L1graphify-out/cache/ast/v0.9.29/107c774c59ce86f256e108b38364b6606584460b17d44294abbbc3de5da6a2a2.json#L1-L1
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@graphify-out/cache/ast/v0.9.29/070ed0dfafd8310a243b51cc30b1b6dfb19883fdd5ad20e4b53e45eb7f939e3e.json`
at line 1, Normalize machine-specific absolute workspace paths in the generated
Graphify caches. In
graphify-out/cache/ast/v0.9.29/070ed0dfafd8310a243b51cc30b1b6dfb19883fdd5ad20e4b53e45eb7f939e3e.json:1-1,
07e40705140f96139361d29ad46bce8cdb8303339171f45cb1436780d4da58f3.json:1-1, and
08e79622b777468d92f233b7c30b8ed76c9c48ad03597affb7c92c1d49dc681b.json:1-1,
regenerate node IDs using repository-relative paths; in
graphify-out/cache/ast/v0.9.29/107c774c59ce86f256e108b38364b6606584460b17d44294abbbc3de5da6a2a2.json:1-1,
replace the absolute target_file value with its repository-relative path.
| @@ -0,0 +1 @@ | |||
| {"nodes": [{"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "label": "package.json", "file_type": "code", "source_file": "package.json", "source_location": "L1"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_name", "label": "name", "file_type": "code", "source_file": "package.json", "source_location": "L2"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_version", "label": "version", "file_type": "code", "source_file": "package.json", "source_location": "L3"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_description", "label": "description", "file_type": "code", "source_file": "package.json", "source_location": "L4"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "label": "scripts", "file_type": "code", "source_file": "package.json", "source_location": "L5"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_dev", "label": "dev", "file_type": "code", "source_file": "package.json", "source_location": "L6"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_start", "label": "start", "file_type": "code", "source_file": "package.json", "source_location": "L7"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_lint", "label": "lint", "file_type": "code", "source_file": "package.json", "source_location": "L8"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_lint_check", "label": "lint:check", "file_type": "code", "source_file": "package.json", "source_location": "L9"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_build", "label": "build", "file_type": "code", "source_file": "package.json", "source_location": "L10"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_build_check", "label": "build:check", "file_type": "code", "source_file": "package.json", "source_location": "L11"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_test", "label": "test", "file_type": "code", "source_file": "package.json", "source_location": "L12"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_stryker", "label": "stryker", "file_type": "code", "source_file": "package.json", "source_location": "L13"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_keywords", "label": "keywords", "file_type": "code", "source_file": "package.json", "source_location": "L15"}, {"id": "ref_express", "label": "express", "file_type": "concept", "source_file": "package.json", "source_location": "L15"}, {"id": "ref_auth", "label": "auth", "file_type": "concept", "source_file": "package.json", "source_location": "L15"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_main", "label": "main", "file_type": "code", "source_file": "package.json", "source_location": "L19"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_author", "label": "author", "file_type": "code", "source_file": "package.json", "source_location": "L20"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_license", "label": "license", "file_type": "code", "source_file": "package.json", "source_location": "L21"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_bugs", "label": "bugs", "file_type": "code", "source_file": "package.json", "source_location": "L22"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_bugs_url", "label": "url", "file_type": "code", "source_file": "package.json", "source_location": "L23"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_homepage", "label": "homepage", "file_type": "code", "source_file": "package.json", "source_location": "L25"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_engines", "label": "engines", "file_type": "code", "source_file": "package.json", "source_location": "L26"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_engines_node", "label": "node", "file_type": "code", "source_file": "package.json", "source_location": "L27"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "label": "dependencies", "file_type": "code", "source_file": "package.json", "source_location": "L29"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_api", "label": "@opentelemetry/api", "file_type": "code", "source_file": "package.json", "source_location": "L30"}, {"id": "opentelemetry_api", "label": "@opentelemetry/api", "file_type": "concept", "source_file": "package.json", "source_location": "L30"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_auto_instrumentations_node", "label": "@opentelemetry/auto-instrumentations-node", "file_type": "code", "source_file": "package.json", "source_location": "L31"}, {"id": "opentelemetry_auto_instrumentations_node", "label": "@opentelemetry/auto-instrumentations-node", "file_type": "concept", "source_file": "package.json", "source_location": "L31"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_logs_otlp_grpc", "label": "@opentelemetry/exporter-logs-otlp-grpc", "file_type": "code", "source_file": "package.json", "source_location": "L32"}, {"id": "opentelemetry_exporter_logs_otlp_grpc", "label": "@opentelemetry/exporter-logs-otlp-grpc", "file_type": "concept", "source_file": "package.json", "source_location": "L32"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_logs_otlp_http", "label": "@opentelemetry/exporter-logs-otlp-http", "file_type": "code", "source_file": "package.json", "source_location": "L33"}, {"id": "opentelemetry_exporter_logs_otlp_http", "label": "@opentelemetry/exporter-logs-otlp-http", "file_type": "concept", "source_file": "package.json", "source_location": "L33"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_metrics_otlp_http", "label": "@opentelemetry/exporter-metrics-otlp-http", "file_type": "code", "source_file": "package.json", "source_location": "L34"}, {"id": "opentelemetry_exporter_metrics_otlp_http", "label": "@opentelemetry/exporter-metrics-otlp-http", "file_type": "concept", "source_file": "package.json", "source_location": "L34"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_trace_otlp_grpc", "label": "@opentelemetry/exporter-trace-otlp-grpc", "file_type": "code", "source_file": "package.json", "source_location": "L35"}, {"id": "opentelemetry_exporter_trace_otlp_grpc", "label": "@opentelemetry/exporter-trace-otlp-grpc", "file_type": "concept", "source_file": "package.json", "source_location": "L35"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_trace_otlp_http", "label": "@opentelemetry/exporter-trace-otlp-http", "file_type": "code", "source_file": "package.json", "source_location": "L36"}, {"id": "opentelemetry_exporter_trace_otlp_http", "label": "@opentelemetry/exporter-trace-otlp-http", "file_type": "concept", "source_file": "package.json", "source_location": "L36"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_express", "label": "@opentelemetry/instrumentation-express", "file_type": "code", "source_file": "package.json", "source_location": "L37"}, {"id": "opentelemetry_instrumentation_express", "label": "@opentelemetry/instrumentation-express", "file_type": "concept", "source_file": "package.json", "source_location": "L37"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_http", "label": "@opentelemetry/instrumentation-http", "file_type": "code", "source_file": "package.json", "source_location": "L38"}, {"id": "opentelemetry_instrumentation_http", "label": "@opentelemetry/instrumentation-http", "file_type": "concept", "source_file": "package.json", "source_location": "L38"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_pino", "label": "@opentelemetry/instrumentation-pino", "file_type": "code", "source_file": "package.json", "source_location": "L39"}, {"id": "opentelemetry_instrumentation_pino", "label": "@opentelemetry/instrumentation-pino", "file_type": "concept", "source_file": "package.json", "source_location": "L39"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_winston", "label": "@opentelemetry/instrumentation-winston", "file_type": "code", "source_file": "package.json", "source_location": "L40"}, {"id": "opentelemetry_instrumentation_winston", "label": "@opentelemetry/instrumentation-winston", "file_type": "concept", "source_file": "package.json", "source_location": "L40"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_resources", "label": "@opentelemetry/resources", "file_type": "code", "source_file": "package.json", "source_location": "L41"}, {"id": "opentelemetry_resources", "label": "@opentelemetry/resources", "file_type": "concept", "source_file": "package.json", "source_location": "L41"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_logs", "label": "@opentelemetry/sdk-logs", "file_type": "code", "source_file": "package.json", "source_location": "L42"}, {"id": "opentelemetry_sdk_logs", "label": "@opentelemetry/sdk-logs", "file_type": "concept", "source_file": "package.json", "source_location": "L42"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_metrics", "label": "@opentelemetry/sdk-metrics", "file_type": "code", "source_file": "package.json", "source_location": "L43"}, {"id": "opentelemetry_sdk_metrics", "label": "@opentelemetry/sdk-metrics", "file_type": "concept", "source_file": "package.json", "source_location": "L43"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_node", "label": "@opentelemetry/sdk-node", "file_type": "code", "source_file": "package.json", "source_location": "L44"}, {"id": "opentelemetry_sdk_node", "label": "@opentelemetry/sdk-node", "file_type": "concept", "source_file": "package.json", "source_location": "L44"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_semantic_conventions", "label": "@opentelemetry/semantic-conventions", "file_type": "code", "source_file": "package.json", "source_location": "L45"}, {"id": "opentelemetry_semantic_conventions", "label": "@opentelemetry/semantic-conventions", "file_type": "concept", "source_file": "package.json", "source_location": "L45"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_winston_transport", "label": "@opentelemetry/winston-transport", "file_type": "code", "source_file": "package.json", "source_location": "L46"}, {"id": "opentelemetry_winston_transport", "label": "@opentelemetry/winston-transport", "file_type": "concept", "source_file": "package.json", "source_location": "L46"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_valkey_valkey_glide", "label": "@valkey/valkey-glide", "file_type": "code", "source_file": "package.json", "source_location": "L47"}, {"id": "valkey_valkey_glide", "label": "@valkey/valkey-glide", "file_type": "concept", "source_file": "package.json", "source_location": "L47"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_bcrypt", "label": "bcrypt", "file_type": "code", "source_file": "package.json", "source_location": "L48"}, {"id": "bcrypt", "label": "bcrypt", "file_type": "concept", "source_file": "package.json", "source_location": "L48"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_body_parser", "label": "body-parser", "file_type": "code", "source_file": "package.json", "source_location": "L49"}, {"id": "body_parser", "label": "body-parser", "file_type": "concept", "source_file": "package.json", "source_location": "L49"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_cors", "label": "cors", "file_type": "code", "source_file": "package.json", "source_location": "L50"}, {"id": "cors", "label": "cors", "file_type": "concept", "source_file": "package.json", "source_location": "L50"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_dotenv", "label": "dotenv", "file_type": "code", "source_file": "package.json", "source_location": "L51"}, {"id": "dotenv", "label": "dotenv", "file_type": "concept", "source_file": "package.json", "source_location": "L51"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_express", "label": "express", "file_type": "code", "source_file": "package.json", "source_location": "L52"}, {"id": "express", "label": "express", "file_type": "concept", "source_file": "package.json", "source_location": "L52"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_helmet", "label": "helmet", "file_type": "code", "source_file": "package.json", "source_location": "L53"}, {"id": "helmet", "label": "helmet", "file_type": "concept", "source_file": "package.json", "source_location": "L53"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_joi", "label": "joi", "file_type": "code", "source_file": "package.json", "source_location": "L54"}, {"id": "joi", "label": "joi", "file_type": "concept", "source_file": "package.json", "source_location": "L54"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_jsonwebtoken", "label": "jsonwebtoken", "file_type": "code", "source_file": "package.json", "source_location": "L55"}, {"id": "jsonwebtoken", "label": "jsonwebtoken", "file_type": "concept", "source_file": "package.json", "source_location": "L55"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_kafkajs", "label": "kafkajs", "file_type": "code", "source_file": "package.json", "source_location": "L56"}, {"id": "kafkajs", "label": "kafkajs", "file_type": "concept", "source_file": "package.json", "source_location": "L56"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_knex", "label": "knex", "file_type": "code", "source_file": "package.json", "source_location": "L57"}, {"id": "knex", "label": "knex", "file_type": "concept", "source_file": "package.json", "source_location": "L57"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_otpauth", "label": "otpauth", "file_type": "code", "source_file": "package.json", "source_location": "L58"}, {"id": "otpauth", "label": "otpauth", "file_type": "concept", "source_file": "package.json", "source_location": "L58"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pg", "label": "pg", "file_type": "code", "source_file": "package.json", "source_location": "L59"}, {"id": "pg", "label": "pg", "file_type": "concept", "source_file": "package.json", "source_location": "L59"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pino", "label": "pino", "file_type": "code", "source_file": "package.json", "source_location": "L60"}, {"id": "pino", "label": "pino", "file_type": "concept", "source_file": "package.json", "source_location": "L60"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pino_http", "label": "pino-http", "file_type": "code", "source_file": "package.json", "source_location": "L61"}, {"id": "pino_http", "label": "pino-http", "file_type": "concept", "source_file": "package.json", "source_location": "L61"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_prom_client", "label": "prom-client", "file_type": "code", "source_file": "package.json", "source_location": "L62"}, {"id": "prom_client", "label": "prom-client", "file_type": "concept", "source_file": "package.json", "source_location": "L62"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_swagger_ui_express", "label": "swagger-ui-express", "file_type": "code", "source_file": "package.json", "source_location": "L63"}, {"id": "swagger_ui_express", "label": "swagger-ui-express", "file_type": "concept", "source_file": "package.json", "source_location": "L63"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_winston", "label": "winston", "file_type": "code", "source_file": "package.json", "source_location": "L64"}, {"id": "winston", "label": "winston", "file_type": "concept", "source_file": "package.json", "source_location": "L64"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_zxcvbn", "label": "zxcvbn", "file_type": "code", "source_file": "package.json", "source_location": "L65"}, {"id": "zxcvbn", "label": "zxcvbn", "file_type": "concept", "source_file": "package.json", "source_location": "L65"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "label": "devDependencies", "file_type": "code", "source_file": "package.json", "source_location": "L67"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_commitlint_cli", "label": "@commitlint/cli", "file_type": "code", "source_file": "package.json", "source_location": "L68"}, {"id": "commitlint_cli", "label": "@commitlint/cli", "file_type": "concept", "source_file": "package.json", "source_location": "L68"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_commitlint_config_conventional", "label": "@commitlint/config-conventional", "file_type": "code", "source_file": "package.json", "source_location": "L69"}, {"id": "commitlint_config_conventional", "label": "@commitlint/config-conventional", "file_type": "concept", "source_file": "package.json", "source_location": "L69"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_css", "label": "@eslint/css", "file_type": "code", "source_file": "package.json", "source_location": "L70"}, {"id": "eslint_css", "label": "@eslint/css", "file_type": "concept", "source_file": "package.json", "source_location": "L70"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_js", "label": "@eslint/js", "file_type": "code", "source_file": "package.json", "source_location": "L71"}, {"id": "eslint_js", "label": "@eslint/js", "file_type": "concept", "source_file": "package.json", "source_location": "L71"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_json", "label": "@eslint/json", "file_type": "code", "source_file": "package.json", "source_location": "L72"}, {"id": "eslint_json", "label": "@eslint/json", "file_type": "concept", "source_file": "package.json", "source_location": "L72"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_markdown", "label": "@eslint/markdown", "file_type": "code", "source_file": "package.json", "source_location": "L73"}, {"id": "eslint_markdown", "label": "@eslint/markdown", "file_type": "concept", "source_file": "package.json", "source_location": "L73"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_stryker_mutator_core", "label": "@stryker-mutator/core", "file_type": "code", "source_file": "package.json", "source_location": "L74"}, {"id": "stryker_mutator_core", "label": "@stryker-mutator/core", "file_type": "concept", "source_file": "package.json", "source_location": "L74"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_stryker_mutator_jest_runner", "label": "@stryker-mutator/jest-runner", "file_type": "code", "source_file": "package.json", "source_location": "L75"}, {"id": "stryker_mutator_jest_runner", "label": "@stryker-mutator/jest-runner", "file_type": "concept", "source_file": "package.json", "source_location": "L75"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_kafka", "label": "@testcontainers/kafka", "file_type": "code", "source_file": "package.json", "source_location": "L76"}, {"id": "testcontainers_kafka", "label": "@testcontainers/kafka", "file_type": "concept", "source_file": "package.json", "source_location": "L76"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_postgresql", "label": "@testcontainers/postgresql", "file_type": "code", "source_file": "package.json", "source_location": "L77"}, {"id": "testcontainers_postgresql", "label": "@testcontainers/postgresql", "file_type": "concept", "source_file": "package.json", "source_location": "L77"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_valkey", "label": "@testcontainers/valkey", "file_type": "code", "source_file": "package.json", "source_location": "L78"}, {"id": "testcontainers_valkey", "label": "@testcontainers/valkey", "file_type": "concept", "source_file": "package.json", "source_location": "L78"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_bcrypt", "label": "@types/bcrypt", "file_type": "code", "source_file": "package.json", "source_location": "L79"}, {"id": "types_bcrypt", "label": "@types/bcrypt", "file_type": "concept", "source_file": "package.json", "source_location": "L79"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_chai", "label": "@types/chai", "file_type": "code", "source_file": "package.json", "source_location": "L80"}, {"id": "types_chai", "label": "@types/chai", "file_type": "concept", "source_file": "package.json", "source_location": "L80"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_cors", "label": "@types/cors", "file_type": "code", "source_file": "package.json", "source_location": "L81"}, {"id": "types_cors", "label": "@types/cors", "file_type": "concept", "source_file": "package.json", "source_location": "L81"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_eslint_plugin_security", "label": "@types/eslint-plugin-security", "file_type": "code", "source_file": "package.json", "source_location": "L82"}, {"id": "types_eslint_plugin_security", "label": "@types/eslint-plugin-security", "file_type": "concept", "source_file": "package.json", "source_location": "L82"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_express", "label": "@types/express", "file_type": "code", "source_file": "package.json", "source_location": "L83"}, {"id": "types_express", "label": "@types/express", "file_type": "concept", "source_file": "package.json", "source_location": "L83"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_jest", "label": "@types/jest", "file_type": "code", "source_file": "package.json", "source_location": "L84"}, {"id": "types_jest", "label": "@types/jest", "file_type": "concept", "source_file": "package.json", "source_location": "L84"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_jsonwebtoken", "label": "@types/jsonwebtoken", "file_type": "code", "source_file": "package.json", "source_location": "L85"}, {"id": "types_jsonwebtoken", "label": "@types/jsonwebtoken", "file_type": "concept", "source_file": "package.json", "source_location": "L85"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_node", "label": "@types/node", "file_type": "code", "source_file": "package.json", "source_location": "L86"}, {"id": "types_node", "label": "@types/node", "file_type": "concept", "source_file": "package.json", "source_location": "L86"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_supertest", "label": "@types/supertest", "file_type": "code", "source_file": "package.json", "source_location": "L87"}, {"id": "types_supertest", "label": "@types/supertest", "file_type": "concept", "source_file": "package.json", "source_location": "L87"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_swagger_ui_express", "label": "@types/swagger-ui-express", "file_type": "code", "source_file": "package.json", "source_location": "L88"}, {"id": "types_swagger_ui_express", "label": "@types/swagger-ui-express", "file_type": "concept", "source_file": "package.json", "source_location": "L88"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_zxcvbn", "label": "@types/zxcvbn", "file_type": "code", "source_file": "package.json", "source_location": "L89"}, {"id": "types_zxcvbn", "label": "@types/zxcvbn", "file_type": "concept", "source_file": "package.json", "source_location": "L89"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript_eslint_parser", "label": "@typescript-eslint/parser", "file_type": "code", "source_file": "package.json", "source_location": "L90"}, {"id": "typescript_eslint_parser", "label": "@typescript-eslint/parser", "file_type": "concept", "source_file": "package.json", "source_location": "L90"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_casual", "label": "casual", "file_type": "code", "source_file": "package.json", "source_location": "L91"}, {"id": "casual", "label": "casual", "file_type": "concept", "source_file": "package.json", "source_location": "L91"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_chai", "label": "chai", "file_type": "code", "source_file": "package.json", "source_location": "L92"}, {"id": "chai", "label": "chai", "file_type": "concept", "source_file": "package.json", "source_location": "L92"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint", "label": "eslint", "file_type": "code", "source_file": "package.json", "source_location": "L93"}, {"id": "eslint", "label": "eslint", "file_type": "concept", "source_file": "package.json", "source_location": "L93"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_plugin_security", "label": "eslint-plugin-security", "file_type": "code", "source_file": "package.json", "source_location": "L94"}, {"id": "eslint_plugin_security", "label": "eslint-plugin-security", "file_type": "concept", "source_file": "package.json", "source_location": "L94"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_plugin_sonarjs", "label": "eslint-plugin-sonarjs", "file_type": "code", "source_file": "package.json", "source_location": "L95"}, {"id": "eslint_plugin_sonarjs", "label": "eslint-plugin-sonarjs", "file_type": "concept", "source_file": "package.json", "source_location": "L95"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_globals", "label": "globals", "file_type": "code", "source_file": "package.json", "source_location": "L96"}, {"id": "globals", "label": "globals", "file_type": "concept", "source_file": "package.json", "source_location": "L96"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_husky", "label": "husky", "file_type": "code", "source_file": "package.json", "source_location": "L97"}, {"id": "husky", "label": "husky", "file_type": "concept", "source_file": "package.json", "source_location": "L97"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_jest", "label": "jest", "file_type": "code", "source_file": "package.json", "source_location": "L98"}, {"id": "jest", "label": "jest", "file_type": "concept", "source_file": "package.json", "source_location": "L98"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nock", "label": "nock", "file_type": "code", "source_file": "package.json", "source_location": "L99"}, {"id": "nock", "label": "nock", "file_type": "concept", "source_file": "package.json", "source_location": "L99"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nodemon", "label": "nodemon", "file_type": "code", "source_file": "package.json", "source_location": "L100"}, {"id": "nodemon", "label": "nodemon", "file_type": "concept", "source_file": "package.json", "source_location": "L100"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nyc", "label": "nyc", "file_type": "code", "source_file": "package.json", "source_location": "L101"}, {"id": "nyc", "label": "nyc", "file_type": "concept", "source_file": "package.json", "source_location": "L101"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_prettier", "label": "prettier", "file_type": "code", "source_file": "package.json", "source_location": "L102"}, {"id": "prettier", "label": "prettier", "file_type": "concept", "source_file": "package.json", "source_location": "L102"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_supertest", "label": "supertest", "file_type": "code", "source_file": "package.json", "source_location": "L103"}, {"id": "supertest", "label": "supertest", "file_type": "concept", "source_file": "package.json", "source_location": "L103"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_jest", "label": "ts-jest", "file_type": "code", "source_file": "package.json", "source_location": "L104"}, {"id": "ts_jest", "label": "ts-jest", "file_type": "concept", "source_file": "package.json", "source_location": "L104"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_mockito", "label": "ts-mockito", "file_type": "code", "source_file": "package.json", "source_location": "L105"}, {"id": "ts_mockito", "label": "ts-mockito", "file_type": "concept", "source_file": "package.json", "source_location": "L105"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_node", "label": "ts-node", "file_type": "code", "source_file": "package.json", "source_location": "L106"}, {"id": "ts_node", "label": "ts-node", "file_type": "concept", "source_file": "package.json", "source_location": "L106"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript", "label": "typescript", "file_type": "code", "source_file": "package.json", "source_location": "L107"}, {"id": "typescript", "label": "typescript", "file_type": "concept", "source_file": "package.json", "source_location": "L107"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript_eslint", "label": "typescript-eslint", "file_type": "code", "source_file": "package.json", "source_location": "L108"}, {"id": "typescript_eslint", "label": "typescript-eslint", "file_type": "concept", "source_file": "package.json", "source_location": "L108"}, {"id": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_w", "label": "w", "file_type": "code", "source_file": "package.json", "source_location": "L109"}, {"id": "w", "label": "w", "file_type": "concept", "source_file": "package.json", "source_location": "L109"}], "edges": [{"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_name", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L2", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_version", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L3", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_description", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L4", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L5", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_dev", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L6", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_start", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L7", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_lint", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L8", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_lint_check", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L9", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_build", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L10", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_build_check", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L11", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_test", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L12", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_scripts_stryker", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L13", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_keywords", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L15", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_keywords", "target": "ref_express", "relation": "extends", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L15", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_keywords", "target": "ref_auth", "relation": "extends", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L15", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_main", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L19", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_author", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L20", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_license", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L21", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_bugs", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L22", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_bugs", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_bugs_url", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L23", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_homepage", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L25", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_engines", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L26", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_engines", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_engines_node", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L27", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L29", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_api", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L30", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_api", "target": "opentelemetry_api", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L30", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_auto_instrumentations_node", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L31", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_auto_instrumentations_node", "target": "opentelemetry_auto_instrumentations_node", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L31", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_logs_otlp_grpc", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L32", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_logs_otlp_grpc", "target": "opentelemetry_exporter_logs_otlp_grpc", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L32", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_logs_otlp_http", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L33", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_logs_otlp_http", "target": "opentelemetry_exporter_logs_otlp_http", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L33", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_metrics_otlp_http", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L34", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_metrics_otlp_http", "target": "opentelemetry_exporter_metrics_otlp_http", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L34", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_trace_otlp_grpc", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L35", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_trace_otlp_grpc", "target": "opentelemetry_exporter_trace_otlp_grpc", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L35", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_trace_otlp_http", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L36", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_exporter_trace_otlp_http", "target": "opentelemetry_exporter_trace_otlp_http", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L36", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_express", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L37", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_express", "target": "opentelemetry_instrumentation_express", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L37", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_http", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L38", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_http", "target": "opentelemetry_instrumentation_http", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L38", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_pino", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L39", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_pino", "target": "opentelemetry_instrumentation_pino", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L39", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_winston", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L40", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_instrumentation_winston", "target": "opentelemetry_instrumentation_winston", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L40", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_resources", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L41", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_resources", "target": "opentelemetry_resources", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L41", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_logs", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L42", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_logs", "target": "opentelemetry_sdk_logs", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L42", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_metrics", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L43", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_metrics", "target": "opentelemetry_sdk_metrics", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L43", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_node", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L44", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_sdk_node", "target": "opentelemetry_sdk_node", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L44", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_semantic_conventions", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L45", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_semantic_conventions", "target": "opentelemetry_semantic_conventions", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L45", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_winston_transport", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L46", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_opentelemetry_winston_transport", "target": "opentelemetry_winston_transport", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L46", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_valkey_valkey_glide", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L47", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_valkey_valkey_glide", "target": "valkey_valkey_glide", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L47", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_bcrypt", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L48", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_bcrypt", "target": "bcrypt", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L48", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_body_parser", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L49", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_body_parser", "target": "body_parser", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L49", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_cors", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L50", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_cors", "target": "cors", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L50", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_dotenv", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L51", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_dotenv", "target": "dotenv", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L51", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_express", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L52", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_express", "target": "express", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L52", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_helmet", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L53", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_helmet", "target": "helmet", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L53", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_joi", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L54", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_joi", "target": "joi", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L54", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_jsonwebtoken", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L55", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_jsonwebtoken", "target": "jsonwebtoken", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L55", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_kafkajs", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L56", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_kafkajs", "target": "kafkajs", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L56", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_knex", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L57", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_knex", "target": "knex", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L57", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_otpauth", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L58", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_otpauth", "target": "otpauth", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L58", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pg", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L59", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pg", "target": "pg", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L59", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pino", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L60", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pino", "target": "pino", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L60", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pino_http", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L61", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_pino_http", "target": "pino_http", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L61", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_prom_client", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L62", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_prom_client", "target": "prom_client", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L62", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_swagger_ui_express", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L63", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_swagger_ui_express", "target": "swagger_ui_express", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L63", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_winston", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L64", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_winston", "target": "winston", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L64", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_zxcvbn", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L65", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_dependencies_zxcvbn", "target": "zxcvbn", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L65", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_json", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L67", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_commitlint_cli", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L68", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_commitlint_cli", "target": "commitlint_cli", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L68", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_commitlint_config_conventional", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L69", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_commitlint_config_conventional", "target": "commitlint_config_conventional", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L69", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_css", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L70", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_css", "target": "eslint_css", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L70", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_js", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L71", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_js", "target": "eslint_js", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L71", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_json", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L72", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_json", "target": "eslint_json", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L72", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_markdown", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L73", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_markdown", "target": "eslint_markdown", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L73", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_stryker_mutator_core", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L74", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_stryker_mutator_core", "target": "stryker_mutator_core", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L74", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_stryker_mutator_jest_runner", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L75", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_stryker_mutator_jest_runner", "target": "stryker_mutator_jest_runner", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L75", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_kafka", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L76", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_kafka", "target": "testcontainers_kafka", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L76", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_postgresql", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L77", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_postgresql", "target": "testcontainers_postgresql", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L77", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_valkey", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L78", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_testcontainers_valkey", "target": "testcontainers_valkey", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L78", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_bcrypt", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L79", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_bcrypt", "target": "types_bcrypt", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L79", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_chai", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L80", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_chai", "target": "types_chai", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L80", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_cors", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L81", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_cors", "target": "types_cors", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L81", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_eslint_plugin_security", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L82", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_eslint_plugin_security", "target": "types_eslint_plugin_security", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L82", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_express", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L83", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_express", "target": "types_express", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L83", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_jest", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L84", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_jest", "target": "types_jest", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L84", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_jsonwebtoken", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L85", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_jsonwebtoken", "target": "types_jsonwebtoken", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L85", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_node", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L86", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_node", "target": "types_node", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L86", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_supertest", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L87", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_supertest", "target": "types_supertest", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L87", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_swagger_ui_express", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L88", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_swagger_ui_express", "target": "types_swagger_ui_express", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L88", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_zxcvbn", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L89", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_types_zxcvbn", "target": "types_zxcvbn", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L89", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript_eslint_parser", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L90", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript_eslint_parser", "target": "typescript_eslint_parser", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L90", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_casual", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L91", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_casual", "target": "casual", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L91", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_chai", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L92", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_chai", "target": "chai", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L92", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L93", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint", "target": "eslint", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L93", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_plugin_security", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L94", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_plugin_security", "target": "eslint_plugin_security", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L94", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_plugin_sonarjs", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L95", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_eslint_plugin_sonarjs", "target": "eslint_plugin_sonarjs", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L95", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_globals", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L96", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_globals", "target": "globals", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L96", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_husky", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L97", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_husky", "target": "husky", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L97", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_jest", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L98", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_jest", "target": "jest", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L98", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nock", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L99", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nock", "target": "nock", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L99", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nodemon", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L100", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nodemon", "target": "nodemon", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L100", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nyc", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L101", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_nyc", "target": "nyc", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L101", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_prettier", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L102", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_prettier", "target": "prettier", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L102", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_supertest", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L103", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_supertest", "target": "supertest", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L103", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_jest", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L104", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_jest", "target": "ts_jest", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L104", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_mockito", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L105", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_mockito", "target": "ts_mockito", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L105", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_node", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L106", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_ts_node", "target": "ts_node", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L106", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L107", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript", "target": "typescript", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L107", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript_eslint", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L108", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_typescript_eslint", "target": "typescript_eslint", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L108", "weight": 1.0, "context": "import"}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies", "target": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_w", "relation": "contains", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L109", "weight": 1.0}, {"source": "home_andrew_documents_auth_plus_symphony_auth_plus_authentication_package_devdependencies_w", "target": "w", "relation": "imports", "confidence": "EXTRACTED", "source_file": "package.json", "source_location": "L109", "weight": 1.0, "context": "import"}]} No newline at end of file | |||
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Sanitize absolute paths before committing Graphify output.
All affected artifacts embed the developer’s local checkout path in generated identifiers; graphify-out/cache/ast/v0.9.29/521bc5c14198bf8f85b2f10cf839fc26cb617b8f4a3510401189402aa041e9b9.json also persists an absolute target_file. Emit repository-relative paths or exclude host-specific caches from version control.
graphify-out/cache/ast/v0.9.29/14bf6d184a95615ed9707b47442e5f55b685e9b0121c61164f5998a799018900.json#L1: normalize package graph node IDs.graphify-out/cache/ast/v0.9.29/23a03f849ef54c3f2b89d56f47bc3851236f539e325de0897b699b57dae7be74.json#L1: normalize quickstart graph node IDs.graphify-out/cache/ast/v0.9.29/2734a509d4b2f34ee6258475c4fb2e80a6dbfcbc47c8552df5b6278907529250.json#L1: normalize template graph node IDs.graphify-out/cache/ast/v0.9.29/2ae70ccc099030710c9a9e142ae83c454ca9f2526d2c0ef94ca42709e5b3342d.json#L1: normalize research graph node IDs.graphify-out/cache/ast/v0.9.29/327b9177caee62513cec0e53459a6ac09f569636f9648e8d77834fba89ad6bfd.json#L1: normalize README graph node IDs.graphify-out/cache/ast/v0.9.29/3c525c42b7d7f51cc46c1ee2a56c266665067b217ecaf76b5bf03775a9b29c4f.json#L1: normalize shell-script graph node IDs.graphify-out/cache/ast/v0.9.29/521bc5c14198bf8f85b2f10cf839fc26cb617b8f4a3510401189402aa041e9b9.json#L1: remove the absolutetarget_fileand normalize node IDs.graphify-out/cache/ast/v0.9.29/64bbd0b8aadc612d601eb49036e7574d6546fe9edc0db0156cb303d1b7ab0ef6.json#L1: normalize TypeScript configuration graph node IDs.graphify-out/cache/ast/v0.9.29/7aefc125bffb446ba63881ed739ddeaacd7402e025fe0782c4b214bb56ca583f.json#L1: normalize plan-template graph node IDs.graphify-out/cache/ast/v0.9.29/9bd6e6dd116b6b29717310b09e26cfd30acdc302612d8f29f2355d2e7ea476c2.json#L1: normalize data-model graph node IDs.
📍 Affects 10 files
graphify-out/cache/ast/v0.9.29/14bf6d184a95615ed9707b47442e5f55b685e9b0121c61164f5998a799018900.json#L1-L1(this comment)graphify-out/cache/ast/v0.9.29/23a03f849ef54c3f2b89d56f47bc3851236f539e325de0897b699b57dae7be74.json#L1-L1graphify-out/cache/ast/v0.9.29/2734a509d4b2f34ee6258475c4fb2e80a6dbfcbc47c8552df5b6278907529250.json#L1-L1graphify-out/cache/ast/v0.9.29/2ae70ccc099030710c9a9e142ae83c454ca9f2526d2c0ef94ca42709e5b3342d.json#L1-L1graphify-out/cache/ast/v0.9.29/327b9177caee62513cec0e53459a6ac09f569636f9648e8d77834fba89ad6bfd.json#L1-L1graphify-out/cache/ast/v0.9.29/3c525c42b7d7f51cc46c1ee2a56c266665067b217ecaf76b5bf03775a9b29c4f.json#L1-L1graphify-out/cache/ast/v0.9.29/521bc5c14198bf8f85b2f10cf839fc26cb617b8f4a3510401189402aa041e9b9.json#L1-L1graphify-out/cache/ast/v0.9.29/64bbd0b8aadc612d601eb49036e7574d6546fe9edc0db0156cb303d1b7ab0ef6.json#L1-L1graphify-out/cache/ast/v0.9.29/7aefc125bffb446ba63881ed739ddeaacd7402e025fe0782c4b214bb56ca583f.json#L1-L1graphify-out/cache/ast/v0.9.29/9bd6e6dd116b6b29717310b09e26cfd30acdc302612d8f29f2355d2e7ea476c2.json#L1-L1
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@graphify-out/cache/ast/v0.9.29/14bf6d184a95615ed9707b47442e5f55b685e9b0121c61164f5998a799018900.json`
at line 1, Sanitize generated Graphify artifacts so host-specific absolute
checkout paths are never persisted. In
graphify-out/cache/ast/v0.9.29/14bf6d184a95615ed9707b47442e5f55b685e9b0121c61164f5998a799018900.json#L1,
normalize package graph node IDs; apply the same node-ID normalization to
graphify-out/cache/ast/v0.9.29/23a03f849ef54c3f2b89d56f47bc3851236f539e325de0897b699b57dae7be74.json#L1,
graphify-out/cache/ast/v0.9.29/2734a509d4b2f34ee6258475c4fb2e80a6dbfcbc47c8552df5b6278907529250.json#L1,
graphify-out/cache/ast/v0.9.29/2ae70ccc099030710c9a9e142ae83c454ca9f2526d2c0ef94ca42709e5b3342d.json#L1,
graphify-out/cache/ast/v0.9.29/327b9177caee62513cec0e53459a6ac09f569636f9648e8d77834fba89ad6bfd.json#L1,
graphify-out/cache/ast/v0.9.29/3c525c42b7d7f51cc46c1ee2a56c266665067b217ecaf76b5bf03775a9b29c4f.json#L1,
graphify-out/cache/ast/v0.9.29/64bbd0b8aadc612d601eb49036e7574d6546fe9edc0db0156cb303d1b7ab0ef6.json#L1,
graphify-out/cache/ast/v0.9.29/7aefc125bffb446ba63881ed739ddeaacd7402e025fe0782c4b214bb56ca583f.json#L1,
and
graphify-out/cache/ast/v0.9.29/9bd6e6dd116b6b29717310b09e26cfd30acdc302612d8f29f2355d2e7ea476c2.json#L1;
additionally remove the absolute target_file from
graphify-out/cache/ast/v0.9.29/521bc5c14198bf8f85b2f10cf839fc26cb617b8f4a3510401189402aa041e9b9.json#L1
and normalize its node IDs.
| 'DATABASE_DATABASE', | ||
| 'DATABASE_PORT', | ||
| 'CACHE_URL', | ||
| 'LOG_LEVEL', |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify LOG_LEVEL is provided everywhere getEnv() is exercised.
fd -H -t f -e yml -e yaml -e env -e example --exec rg -n --with-filename 'LOG_LEVEL' {} \; 2>/dev/null
rg -n 'LOG_LEVEL' -g '!coverage/**' -g '!graphify-out/**' .
fd -H -t f -g '.env*' -g 'docker-compose*'
rg -n 'NODE_ENV|env:' docker-compose.ymlRepository: auth-plus/auth-plus-authentication
Length of output: 511
🏁 Script executed:
#!/bin/bash
set -u
echo "== candidate files =="
git ls-files | rg '(^docker-compose|compose|\.env|src/config/enviroment_config\.ts|logger)' || true
echo "== enviroment_config outline =="
ast-grep outline src/config/enviroment_config.ts --view expanded || true
echo "== enviroment_config relevant lines =="
cat -n src/config/enviroment_config.ts | sed -n '1,95p'
echo "== logger references =="
fd -H -t f src -g 'logger.ts' -x sh -c 'echo "--- $1"; cat -n "$1" | sed -n "1,120p"' sh {}
echo "== getEnv call sites =="
rg -n 'getEnv\(\)|process\.env\.LOG_LEVEL|LOG_LEVEL' -g '!coverage/**' -g '!graphify-out/**' .Repository: auth-plus/auth-plus-authentication
Length of output: 5054
🏁 Script executed:
#!/bin/bash
set -u
echo "== docker-compose env references =="
cat -n docker-compose.yml | sed -n '1,180p'
echo "== logger.ts =="
cat -n src/config/logger.ts | sed -n '1,80p'
echo "== server.ts =="
cat -n src/presentation/http/server.ts | sed -n '1,80p'
echo "== index.ts =="
cat -n src/core/index.ts | sed -n '1,90p'
echo "== package scripts =="
json --indent 4 .package.json 2>/dev/null || sed -n '1,120p' package.jsonRepository: auth-plus/auth-plus-authentication
Length of output: 14418
🌐 Web query:
pino logger allowed levels trace debug info warn error fatal
💡 Result:
Pino uses a hierarchical logging system based on numerical values to determine which logs are processed. The standard logging levels, ordered from lowest severity to highest, are trace, debug, info, warn, error, and fatal [1][2][3]. The logger can also be set to silent, which disables all logging [1][2]. Each level is associated with a specific numerical value [1][2]: Level: trace | Value: 10 Level: debug | Value: 20 Level: info | Value: 30 Level: warn | Value: 40 Level: error | Value: 50 Level: fatal | Value: 60 Level: silent | Value: Infinity Pino processes logs based on a minimum threshold [1][2]. When you set the logger's level (e.g., via the level option in the constructor or by setting logger.level), Pino will only output logs with a value greater than or equal to the threshold associated with that level [1][4][5]. For example, if the level is set to info (30), Pino will log info, warn, error, and fatal messages, but will ignore trace and debug messages [1][2][3]. Additional custom levels can be defined using the customLevels option if needed [1][2].
Citations:
- 1: https://github.com/pinojs/pino/blob/main/docs/api.md
- 2: https://github.com/pinojs/pino/blob/HEAD/docs/api.md
- 3: https://github.com/pinojs/pino/blob/v5.13.3/docs/api.md
- 4: https://github.com/pinojs/pino/blob/v5.3.1/docs/api.md
- 5: https://github.com/pinojs/pino/blob/master/docs/api.md
Avoid forcing LOG_LEVEL through getEnv() at module load.
With LOG_LEVEL mandatory, any local, test, or compose environment without it now throws during module evaluation. Keep LOG_LEVEL optional in mandatoryKeys and derive/validate the logger level from process.env.LOG_LEVEL with a sensible default; otherwise existing envs without it will fail to initialize.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/config/enviroment_config.ts` at line 33, Update the environment
configuration around mandatoryKeys so LOG_LEVEL remains optional and is not
fetched through getEnv() during module initialization. Derive the logger level
directly from process.env.LOG_LEVEL, validate it using the existing logger-level
handling, and apply a sensible default when it is absent.
| serializers: { | ||
| email: (val) => (typeof val === 'string' ? maskEmail(val) : val), | ||
| phone: (val) => (typeof val === 'string' ? maskPhone(val) : val), | ||
| }, | ||
| redact: { | ||
| paths: [ | ||
| 'password', | ||
| 'confirmPassword', | ||
| 'code', | ||
| 'token', | ||
| 'secret', | ||
| 'mfaList[*].secret', | ||
| '*.password', | ||
| '*.confirmPassword', | ||
| '*.code', | ||
| '*.token', | ||
| '*.secret', | ||
| ], | ||
| censor: '[REDACTED]', | ||
| }, |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
pino redact paths nested wildcard depth fast-redact intermediate wildcard support
💡 Result:
Pino's redaction functionality, which relies on the fast-redact library, supports single-level wildcards but does not provide native support for recursive or deep wildcards (often denoted as) [1][2][3]. Key points regarding wildcard usage in Pino and fast-redact include: 1. No Recursive Wildcard Support: There is no recursive wildcard operator (e.g.,) that automatically traverses arbitrary nesting depths [2]. Attempting to use or similar patterns will typically result in the pattern being treated as a literal string or failing to match [2]. 2. Intermediate Wildcard Support: fast-redact does support intermediate wildcards (e.g., a..b) [3][4]. When an asterisk is placed in an intermediate or first position, the library will redact the specified paths for every object found at that level within the parent [3][5]. 3. Manual Depth Handling: Because recursive wildcards are unavailable, you must explicitly define paths for each expected level of nesting to ensure complete coverage [2][6]. A common pattern to achieve this is to programmatically generate an array of paths covering the required depths [2]: const depth = (field) => ['', '.', '..', '...*'].map((p) => `${p}.${field}`); const redactPaths = [...depth('password')]; 4. Performance Considerations: While static paths have negligible overhead, using wildcards—especially intermediate ones—introduces a non-trivial performance cost relative to explicit paths [1][3]. Benchmarks indicate that intermediate wildcard redaction can be significantly more expensive than static path redaction [3][5]. 5. Limitations: Issues have been noted where complex or deeply nested patterns (e.g., 3+ consecutive wildcards) may fail to redact fields correctly depending on the version and implementation, often requiring manual, explicit depth listing for reliability [7][6].
Citations:
- 1: https://github.com/pinojs/pino/blob/main/docs/redaction.md
- 2: https://github.com/bymaxone/nest-logger/blob/main/docs/guidelines/PINO-REDACTION-GUIDELINES.md
- 3: https://www.npmjs.com/package/fast-redact
- 4: https://github.com/davidmarkclements/fast-redact/blob/main/readme.md
- 5: https://github.com/davidmarkclements/fast-redact
- 6: Support for deep-wildcard object redaction davidmarkclements/fast-redact#65
- 7: https://github.com/pinojs/pino/issues/2319
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate logger.ts =="
fd -a 'logger\.ts$' . | sed 's#^\./##'
echo "== read src/config/logger.ts with line numbers =="
cat -n src/config/logger.ts | sed -n '1,120p'
echo "== package pino/fast-redact versions =="
if [ -f package.json ]; then
jq '.dependencies, .devDependencies | to_entries[]? | select(.value?|test("pino|fast-redact";"i"))[]?' package.json || true
fi
if [ -f package-lock.json ]; then
jq '.packages."node_modules/pino".version, .packages."node_modules/fast-redact".version' package-lock.json 2>/dev/null || true
fi
echo "== logger usages with email/password nesting examples =="
rg -n --glob '!node_modules' --glob '!dist' --glob '!build' "logger\.[A-Za-z]+\(|pino\(|serialize|email:|password|confirmPassword|code|token|secret|mfaList" . \
| head -n 300Repository: auth-plus/auth-plus-authentication
Length of output: 31468
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate installed pino package =="
find / -path '*node_modules/pino*' -maxdepth 3 -type f 2>/dev/null | head -n 20 || true
find /usr/local/lib /usr/lib /root -path '*node_modules/pino*' -maxdepth 5 -type f 2>/dev/null | head -n 20 || true
echo "== inspect package-lock pin for pino =="
python3 - <<'PY'
import json
p=json.load(open('package-lock.json'))
for name in ['pino-std-serializers','fast-redact']:
pkg=p.get('packages',{}).get('node_modules/'+name)
print(name, pkg and pkg.get('version'), pkg and pkg.get('resolved'))
PY
echo "== search all logger imports/usages with context =="
rg -n --glob '!node_modules' --glob '!dist' --glob '!build' --glob '!coverage' --glob '!graph.svg' 'from ["'"'"]\.\./config/logger["'"'"]|from ["'"'"]\.\./src/config/logger["'"'"]|logger\.[A-Za-z]+\(' . \
| head -n 400Repository: auth-plus/auth-plus-authentication
Length of output: 14111
Add depth coverage for sensitive fields
Pino’s redaction only supports paths of known depth; the existing *.password and *.token entries won’t catch user.info.password or similar deeper payload shapes. Add the expected nesting levels for sensitive fields, or reshape the logged objects so sensitive values are always at covered paths.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/config/logger.ts` around lines 7 - 26, Extend the redact.paths
configuration in the logger setup to cover sensitive fields at the deeper
nesting levels used by payloads, including paths such as user.info.password and
equivalent password, confirmPassword, code, token, and secret variants. Preserve
the existing top-level and one-level wildcard entries and the current censor
value.
| export function maskEmail(email: string): string { | ||
| if (!email || !email.includes('@')) return email; | ||
| const [local, domain] = email.split('@'); | ||
| if (local.length <= 2) { | ||
| return `${local[0]}***@${domain}`; | ||
| } | ||
| return `${local[0]}***${local[local.length - 1]}@${domain}`; | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
maskEmail truncates addresses containing more than one @.
email.split('@') destructured into two variables discards everything after the second @, so the masked output is a different (wrong) address in logs. Split on the last @ instead.
🐛 Proposed fix
export function maskEmail(email: string): string {
- if (!email || !email.includes('@')) return email;
- const [local, domain] = email.split('@');
+ if (!email) return email;
+ const at = email.lastIndexOf('@');
+ if (at <= 0) return email;
+ const local = email.slice(0, at);
+ const domain = email.slice(at + 1);
if (local.length <= 2) {
return `${local[0]}***@${domain}`;
}
return `${local[0]}***${local[local.length - 1]}@${domain}`;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export function maskEmail(email: string): string { | |
| if (!email || !email.includes('@')) return email; | |
| const [local, domain] = email.split('@'); | |
| if (local.length <= 2) { | |
| return `${local[0]}***@${domain}`; | |
| } | |
| return `${local[0]}***${local[local.length - 1]}@${domain}`; | |
| } | |
| export function maskEmail(email: string): string { | |
| if (!email) return email; | |
| const at = email.lastIndexOf('@'); | |
| if (at <= 0) return email; | |
| const local = email.slice(0, at); | |
| const domain = email.slice(at + 1); | |
| if (local.length <= 2) { | |
| return `${local[0]}***@${domain}`; | |
| } | |
| return `${local[0]}***${local[local.length - 1]}@${domain}`; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/config/logger.ts` around lines 41 - 48, Update maskEmail to split the
address at the last '@' rather than destructuring email.split('@'), preserving
the entire domain—including any additional '@' characters—in the masked output
while keeping the existing local-part masking behavior.
| if (strategy === Strategy.GA && user.info.phone == null) { | ||
| // Note: check user info here if applicable, but original code was using user.info.phone for Strategy.PHONE: | ||
| } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Empty if block — dead code left behind.
This branch has no body, no throw, and no side effect; it only carries a note. It also violates the standard no-empty lint rule, which conflicts with T016 in tasks.md claiming lint passes. Remove it, or implement the intended GA validation.
🧹 Proposed removal
- if (strategy === Strategy.GA && user.info.phone == null) {
- // Note: check user info here if applicable, but original code was using user.info.phone for Strategy.PHONE:
- }
if (strategy === Strategy.PHONE && user.info.phone == null) {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (strategy === Strategy.GA && user.info.phone == null) { | |
| // Note: check user info here if applicable, but original code was using user.info.phone for Strategy.PHONE: | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/core/providers/mfa.repository.ts` around lines 46 - 48, Remove the empty
GA phone-check branch in the MFA repository, including its note, unless
implementing the intended validation is required by surrounding logic. Preserve
the existing strategy handling and ensure no dead empty conditional remains.
| logger.debug({ cacheKeyPattern: 'invalidate:*', action: 'set' }, 'Cache operation executed') | ||
| await this.cache.set(`invalidate:${token}`, token, this.TTL) | ||
| } | ||
|
|
||
| create(user: User): string { | ||
| logger.debug({ action: 'signToken', userId: user.id }, 'JWT token signed') |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Log completion only after the operation succeeds.
Both messages claim completion before cache.set / sign runs. A failure produces a false success record; rename these as “started” or emit them after success.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/core/providers/token.repository.ts` around lines 15 - 20, Update the
debug logging in the token cache invalidation and token creation methods so
completion messages are emitted only after cache.set and token signing succeed,
or rename the pre-operation messages to indicate they started. Ensure failures
do not produce logs claiming successful completion, using the relevant
invalidation method and create method.
Summary by CodeRabbit
New Features
Documentation
Chores