debug-local
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDebugging Lightdash
调试Lightdash
Iron Law
铁则
NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST.
Do not edit application code until you have a confirmed root cause hypothesis backed by evidence (logs, traces, reproduction). Fixing symptoms creates whack-a-mole debugging.
未查明根本原因,绝不修复问题。
在获得由证据(日志、追踪信息、复现步骤)支撑的明确根本原因假设之前,请勿修改应用代码。仅修复症状会导致调试陷入“打地鼠”式的恶性循环。
Phase 1: Gather Evidence
第一阶段:收集证据
Before forming any hypothesis, collect facts.
在形成任何假设之前,先收集事实信息。
1. Collect symptoms
1. 收集症状信息
Read error messages, stack traces, and reproduction steps. If the user hasn't provided enough context, ask ONE clarifying question.
阅读错误信息、堆栈追踪和复现步骤。如果用户提供的上下文不足,提出一个明确的澄清问题。
2. Check recent changes
2. 检查近期变更
bash
git log --oneline -20 -- <affected-files>Was this working before? A regression means the root cause is in the diff.
bash
git log --oneline -20 -- <affected-files>之前功能是否正常?如果是回归问题,说明根本原因存在于代码差异中。
3. Check logs and traces
3. 检查日志与追踪信息
bash
pnpm exec pm2 logs lightdash-api --lines 50 --nostreamThen use Spotlight MCP:
- with
mcp__spotlight__search_errorsfor recent errors with stack traces{"timeWindow": 300} - with
mcp__spotlight__search_tracesfor recent request traces{"timeWindow": 300} - with a trace ID for full span breakdown
mcp__spotlight__get_traces
bash
pnpm exec pm2 logs lightdash-api --lines 50 --nostream然后使用Spotlight MCP:
- 使用并设置
mcp__spotlight__search_errors,查看包含堆栈追踪的近期错误{"timeWindow": 300} - 使用并设置
mcp__spotlight__search_traces,查看近期请求追踪{"timeWindow": 300} - 使用并传入trace ID,获取完整的调用链路 breakdown
mcp__spotlight__get_traces
4. Reproduce
4. 复现问题
Can you trigger the bug deterministically? Use browser automation or curl to reproduce. If you can't reproduce, gather more evidence before proceeding.
能否稳定触发bug?使用浏览器自动化工具或curl命令复现。如果无法复现,先收集更多证据再继续。
5. Read the code
5. 阅读代码
Trace the code path from the symptom back to potential causes. Use Grep to find all references, Read to understand the logic.
Output: State your root cause hypothesis — a specific, testable claim about what is wrong and why.
从症状出发反向追踪代码路径,定位潜在原因。使用Grep查找所有引用,阅读代码理解逻辑。
输出: 明确你的根本原因假设——关于问题所在及原因的具体、可验证的论断。
Phase 2: Pattern Matching
第二阶段:模式匹配
Check if the bug matches a known Lightdash pattern:
| Pattern | Signature | Where to look |
|---|---|---|
| Permission error | 403 Forbidden | CASL abilities in |
| Slow query / N+1 | Response >1s, many db spans | Spotlight span breakdown — count db.* spans, check for loops |
| Stale explore cache | Shows old columns/metrics | |
| Migration issue | Column not found, schema mismatch | |
| Scheduler job failure | Job not running, stuck | PM2 scheduler logs, |
| Frontend stale data | UI shows old data after mutation | TanStack Query cache invalidation, check |
| Race condition | Intermittent, timing-dependent | Concurrent access to shared state, missing |
| Cross-service file issue | File not found in worker/headless | Must use S3 via |
| Config drift | Works locally, fails in CI/staging | Env vars, |
| Null propagation | TypeError, cannot read property | Missing guards on optional values, Knex |
Also check:
- for prior fixes in the same area — recurring bugs in the same files are an architectural smell
git log - Whether the issue is in common, backend, or frontend — misattributing the layer wastes time
检查bug是否符合已知的Lightdash问题模式:
| 模式 | 特征 | 排查位置 |
|---|---|---|
| 权限错误 | 403 Forbidden | |
| 查询缓慢 / N+1问题 | 响应时间>1秒,存在大量数据库调用链路 | Spotlight链路breakdown——统计db.*链路数量,检查是否存在循环 |
| Explore缓存过期 | 显示旧的列/指标 | |
| 迁移问题 | 列不存在、 schema不匹配 | |
| 调度任务失败 | 任务未运行、停滞 | PM2调度日志、 |
| 前端数据过期 | 执行变更后UI仍显示旧数据 | TanStack Query缓存失效机制,检查 |
| 竞态条件 | 间歇性问题、与时间相关 | 共享状态的并发访问、缺失 |
| 跨服务文件问题 | 工作节点/无头服务中找不到文件 | 必须通过 |
| 配置漂移 | 本地正常,CI/预发布环境失败 | 环境变量, |
| Null值传播 | TypeError,无法读取属性 | 可选值缺失保护、Knex |
同时检查:
- 中同一区域的过往修复记录——同一文件反复出现bug属于架构缺陷
git log - 问题属于通用模块、后端还是前端——错误归因会浪费时间
Phase 3: Hypothesis Testing
第三阶段:假设验证
Before writing ANY fix, verify your hypothesis.
-
Confirm: Add a temporary log, assertion, or use Spotlight/PM2 to check the suspected root cause. Reproduce. Does evidence match?
-
If wrong: Return to Phase 1. Gather more evidence. Do not guess.
-
3-strike rule: If 3 hypotheses fail, STOP. Ask the user:
- Continue with a new hypothesis (describe it)
- Escalate for human review
- Add instrumentation and wait to catch it next time
在编写任何修复代码之前,先验证你的假设。
-
确认:添加临时日志、断言,或使用Spotlight/PM2检查疑似根本原因。复现问题,证据是否匹配?
-
若假设错误:回到第一阶段,收集更多证据。请勿猜测。
-
三次失败规则:如果3个假设均不成立,停止操作。询问用户:
- 继续验证新的假设(描述该假设)
- 升级请求人工审核
- 添加监控,等待下次捕获问题
Phase 4: Fix
第四阶段:修复
Once root cause is confirmed:
-
Fix the root cause, not the symptom. Smallest change that eliminates the actual problem.
-
Minimal diff. Fewest files touched, fewest lines changed. Do not refactor adjacent code.
-
Write a regression test that fails without the fix and passes with it.
-
Run the relevant test suite. Paste output.
-
Blast radius check: If fix touches >5 files, pause and confirm with the user before proceeding.
确认根本原因后:
-
修复根本原因,而非症状:采用最小化改动消除实际问题。
-
最小化代码差异:修改最少的文件和代码行数。请勿重构相邻代码。
-
编写回归测试:确保无修复时测试失败,修复后测试通过。
-
运行相关测试套件:粘贴测试输出。
-
影响范围检查:如果修复涉及超过5个文件,请暂停并先与用户确认。
Phase 5: Verify & Report
第五阶段:验证与报告
Reproduce the original bug scenario and confirm it's fixed. This is not optional.
Output a structured debug report:
DEBUG REPORT
════════════════════════════════════════
Symptom: [what the user observed]
Root cause: [what was actually wrong]
Fix: [what was changed, with file:line references]
Evidence: [test output, trace showing fix works]
Regression test: [file:line of the new test]
Status: DONE | DONE_WITH_CONCERNS | BLOCKED
════════════════════════════════════════Status definitions:
- DONE — root cause found, fix applied, regression test written, tests pass
- DONE_WITH_CONCERNS — fixed but cannot fully verify (e.g., intermittent bug, needs staging)
- BLOCKED — root cause unclear after investigation, escalated to user
复现原始bug场景,确认问题已修复。 此步骤不可省略。
输出结构化调试报告:
DEBUG REPORT
════════════════════════════════════════
症状: [用户观察到的现象]
根本原因: [实际问题所在]
修复方案: [修改内容,包含文件:行号引用]
证据: [测试输出、验证修复有效的追踪信息]
回归测试: [新测试的文件:行号]
状态: DONE | DONE_WITH_CONCERNS | BLOCKED
════════════════════════════════════════状态定义:
- DONE — 已找到根本原因,完成修复,编写回归测试,测试通过
- DONE_WITH_CONCERNS — 已修复但无法完全验证(如间歇性bug、需要预发布环境验证)
- BLOCKED — 调查后仍无法明确根本原因,已升级给用户
Prerequisites
前置条件
Ensure the development environment is running:
bash
/docker-dev # Start Docker services (postgres, minio, etc.)
pnpm pm2:start # Start all PM2 processes including Spotlight
pnpm pm2:status # Verify all processes are onlineServices:
- Frontend: http://localhost:3000
- API: http://localhost:8080
- Spotlight UI: http://localhost:8969
确保开发环境已运行:
bash
/docker-dev # 启动Docker服务(postgres、minio等)
pnpm pm2:start # 启动所有PM2进程,包括Spotlight
pnpm pm2:status # 验证所有进程已在线服务地址:
- 前端: http://localhost:3000
- API: http://localhost:8080
- Spotlight UI: http://localhost:8969
Tools Reference
工具参考
Server Logs (PM2)
服务器日志(PM2)
bash
pnpm pm2:logs # Stream all logs (Ctrl+C to exit)
pnpm pm2:logs:api # API server logs only
pnpm pm2:logs:scheduler # Background job scheduler logs
pnpm pm2:logs:frontend # Vite dev server logs
pnpm pm2:logs:spotlight # Spotlight sidecar logsFor non-blocking log viewing (last N lines):
bash
pnpm exec pm2 logs lightdash-api --lines 20 --nostreambash
pnpm pm2:logs # 流式查看所有日志(按Ctrl+C退出)
pnpm pm2:logs:api # 仅查看API服务器日志
pnpm pm2:logs:scheduler # 查看后台任务调度日志
pnpm pm2:logs:frontend # 查看Vite开发服务器日志
pnpm pm2:logs:spotlight # 查看Spotlight边车服务日志非阻塞式查看日志(最近N行):
bash
pnpm exec pm2 logs lightdash-api --lines 20 --nostreamLog format
日志格式
Lightdash logs include a 32-character trace ID for correlation:
[700aa55e784a437aa97de9b8c5c3ed3a] GET /api/v1/health 200 - 37 ms
[4d40816e5a7d433e88f99008de5f4be5] GET /api/v1/user/login-options 200 - 2 msUse the first 8 characters (e.g., ) to look up traces in Spotlight.
700aa55eLightdash日志包含用于关联的32位trace ID:
[700aa55e784a437aa97de9b8c5c3ed3a] GET /api/v1/health 200 - 37 ms
[4d40816e5a7d433e88f99008de5f4be5] GET /api/v1/user/login-options 200 - 2 ms使用前8个字符(如)在Spotlight中查找对应追踪信息。
700aa55eTrace Lookup (Spotlight MCP)
追踪信息查询(Spotlight MCP)
Use the Spotlight MCP tools to query telemetry programmatically:
使用Spotlight MCP工具以编程方式查询遥测数据:
List recent traces
列出近期追踪信息
mcp__spotlight__search_traces with filters: {"timeWindow": 300}Returns summary of recent traces with trace ID, endpoint, duration, span count.
mcp__spotlight__search_traces with filters: {"timeWindow": 300}返回近期追踪信息摘要,包含trace ID、端点、耗时、链路数量。
Get trace details
获取追踪详情
mcp__spotlight__get_traces with traceId: "700aa55e"Returns the full span tree with timing breakdown:
GET /api/v1/health [816224a9 · 39ms]
├─ select * from "knex_migrations" [db · 8ms]
├─ select * from "organizations" [db · 2ms]
├─ session [middleware.express · 1ms]
└─ /api/v1/health [request_handler.express · 0ms]mcp__spotlight__get_traces with traceId: "700aa55e"返回完整的调用链路树及时间 breakdown:
GET /api/v1/health [816224a9 · 39ms]
├─ select * from "knex_migrations" [db · 8ms]
├─ select * from "organizations" [db · 2ms]
├─ session [middleware.express · 1ms]
└─ /api/v1/health [request_handler.express · 0ms]Search for errors
搜索错误
mcp__spotlight__search_errors with filters: {"timeWindow": 300}Returns runtime errors and exceptions with stack traces.
mcp__spotlight__search_errors with filters: {"timeWindow": 300}返回运行时错误和异常及堆栈追踪。
Search logs
搜索日志
mcp__spotlight__search_logs with filters: {"timeWindow": 300}Returns application log entries.
mcp__spotlight__search_logs with filters: {"timeWindow": 300}返回应用日志条目。
Browser Debugging (Chrome DevTools MCP)
浏览器调试(Chrome DevTools MCP)
Use the Chrome DevTools MCP tools for browser automation:
使用Chrome DevTools MCP工具进行浏览器自动化:
Opening pages
打开页面
mcp__chrome-devtools__new_page with url: "http://localhost:3000/login"
mcp__chrome-devtools__navigate_page with url: "http://localhost:3000", type: "url"mcp__chrome-devtools__new_page with url: "http://localhost:3000/login"
mcp__chrome-devtools__navigate_page with url: "http://localhost:3000", type: "url"Taking snapshots
生成快照
mcp__chrome-devtools__take_snapshotReturns a text snapshot of the page based on the accessibility tree with unique identifiers for each element.
uidmcp__chrome-devtools__take_snapshot基于可访问性树返回页面文本快照,包含每个元素的唯一标识符。
uidInteracting with elements
与元素交互
mcp__chrome-devtools__click with uid: "1_5"
mcp__chrome-devtools__fill with uid: "1_4", value: "test@example.com"
mcp__chrome-devtools__hover with uid: "1_3"mcp__chrome-devtools__click with uid: "1_5"
mcp__chrome-devtools__fill with uid: "1_4", value: "test@example.com"
mcp__chrome-devtools__hover with uid: "1_3"Screenshots
截图
mcp__chrome-devtools__take_screenshot
mcp__chrome-devtools__take_screenshot with fullPage: true
mcp__chrome-devtools__take_screenshot with filePath: "/tmp/debug.png"mcp__chrome-devtools__take_screenshot
mcp__chrome-devtools__take_screenshot with fullPage: true
mcp__chrome-devtools__take_screenshot with filePath: "/tmp/debug.png"Console and network
控制台与网络
mcp__chrome-devtools__list_console_messages
mcp__chrome-devtools__list_network_requests
mcp__chrome-devtools__get_network_request with reqid: 123mcp__chrome-devtools__list_console_messages
mcp__chrome-devtools__list_network_requests
mcp__chrome-devtools__get_network_request with reqid: 123Page management
页面管理
mcp__chrome-devtools__list_pages
mcp__chrome-devtools__select_page with pageId: 1
mcp__chrome-devtools__close_page with pageId: 2mcp__chrome-devtools__list_pages
mcp__chrome-devtools__select_page with pageId: 1
mcp__chrome-devtools__close_page with pageId: 2Database Inspection
数据库检查
bash
undefinedbash
undefinedCheck table schema
检查表结构
psql -c "\d <table_name>"
psql -c "\d <table_name>"
Query data directly
直接查询数据
psql -c "SELECT * FROM <table> WHERE <condition> LIMIT 5;"
psql -c "SELECT * FROM <table> WHERE <condition> LIMIT 5;"
Check scheduler jobs
检查调度任务
psql -c "SELECT id, task_identifier, attempts, last_error FROM graphile_worker.jobs WHERE last_error IS NOT NULL LIMIT 10;"
undefinedpsql -c "SELECT id, task_identifier, attempts, last_error FROM graphile_worker.jobs WHERE last_error IS NOT NULL LIMIT 10;"
undefinedTrace Attributes (Wide Events)
追踪属性(宽事件)
Traces contain contextual attributes beyond timing:
| Attribute | Example | Description |
|---|---|---|
| | Route pattern |
| | Response status |
| | HTTP method |
| | Operation type |
| | Database type |
追踪信息包含除时间外的上下文属性:
| 属性 | 示例 | 描述 |
|---|---|---|
| | 路由模式 |
| | 响应状态码 |
| | HTTP方法 |
| | 操作类型 |
| | 数据库类型 |
Common Debugging Scenarios
常见调试场景
| Symptom | What to check |
|---|---|
| 401 Unauthorized | Trace auth middleware, check session/JWT spans |
| 403 Forbidden | Check user ability/permissions in trace attributes, review CASL abilities |
| 404 Not Found | Verify route exists, check resource lookup spans |
| 400 Bad Request | Look for validation errors in trace/error logs |
| Slow response | Check span breakdown for slow db.* or external calls, count db spans for N+1 |
| Empty results | Verify query parameters, check db query spans |
| 500 Server Error | Use |
| UI not updating | Check TanStack Query devtools, verify cache invalidation after mutations |
| Scheduler not running | Check |
| 症状 | 检查内容 |
|---|---|
| 401 Unauthorized | 追踪认证中间件,检查session/JWT链路 |
| 403 Forbidden | 检查追踪属性中的用户权限,查看CASL abilities |
| 404 Not Found | 验证路由是否存在,检查资源查找链路 |
| 400 Bad Request | 在追踪/错误日志中查找验证错误 |
| 响应缓慢 | 检查链路breakdown中的慢db.*或外部调用,统计数据库链路数量排查N+1问题 |
| 结果为空 | 验证查询参数,检查数据库查询链路 |
| 500 Server Error | 使用 |
| UI未更新 | 检查TanStack Query开发工具,验证变更后的缓存失效机制 |
| 调度器未运行 | 查看 |
Quick Commands Reference
快速命令参考
| Action | Command |
|---|---|
| View all logs | |
| View API logs (non-blocking) | |
| Check process status | |
| Restart API | |
| Recent traces | |
| Trace details | |
| Recent errors | |
| Browser snapshot | |
| Open Spotlight UI | http://localhost:8969 |
| 操作 | 命令 |
|---|---|
| 查看所有日志 | |
| 非阻塞式查看API日志 | |
| 检查进程状态 | |
| 重启API | |
| 查看近期追踪信息 | |
| 查看追踪详情 | |
| 查看近期错误 | |
| 生成浏览器快照 | |
| 打开Spotlight UI | http://localhost:8969 |
Cross-Agent Validation
跨Agent验证
Use another AI agent to validate your findings, challenge your conclusions, and provide independent evidence. This is not just for when you're stuck — actively seek validation throughout the debugging process to ensure your analysis is sound.
使用另一个AI Agent验证你的发现,挑战你的结论,并提供独立证据。这不仅适用于陷入困境时——在整个调试过程中主动寻求验证,确保分析的合理性。
Detect your environment
检测环境
bash
which claude 2>/dev/null && echo "HAS_CLAUDE=true" || echo "HAS_CLAUDE=false"
which codex 2>/dev/null && echo "HAS_CODEX=true" || echo "HAS_CODEX=false"bash
which claude 2>/dev/null && echo "HAS_CLAUDE=true" || echo "HAS_CLAUDE=false"
which codex 2>/dev/null && echo "HAS_CODEX=true" || echo "HAS_CODEX=false"If you are Claude → ask Codex
如果你是Claude → 询问Codex
bash
codex exec "Given this context from a Lightdash debugging session:
<context>
[paste relevant logs, traces, error messages, or code snippets]
</context>
<question>
[your specific question — e.g., 'Does this trace confirm that the query cache is being bypassed?' or 'Given this stack trace, is my conclusion that the middleware short-circuits before auth correct?']
</question>"bash
codex exec "Given this context from a Lightdash debugging session:
<context>
[paste relevant logs, traces, error messages, or code snippets]
</context>
<question>
[your specific question — e.g., 'Does this trace confirm that the query cache is being bypassed?' or 'Given this stack trace, is my conclusion that the middleware short-circuits before auth correct?']
</question>"If you are Codex → ask Claude
如果你是Codex → 询问Claude
bash
claude -p "Given this context from a Lightdash debugging session:
<context>
[paste relevant logs, traces, error messages, or code snippets]
</context>
<question>
[your specific question]
</question>"bash
claude -p "Given this context from a Lightdash debugging session:
<context>
[paste relevant logs, traces, error messages, or code snippets]
</context>
<question>
[your specific question]
</question>"When to consult
咨询时机
- Validate a hypothesis: Before concluding root cause, ask the other agent if the evidence supports your theory or if there's an alternative explanation
- Verify your interpretation of data: When reading traces, logs, or query output — confirm you're reading it correctly
- Challenge your fix: Before suggesting a code change, ask whether the fix actually addresses the root cause or just masks a symptom
- Cross-check complex logic: When the issue involves multiple systems (frontend + API + database + permissions), get an independent read on the interaction
- Justify a conclusion: If you're about to tell the user "X is the cause", make sure another perspective agrees — or surface the disagreement
- 验证假设:在得出根本原因结论前,询问其他Agent证据是否支持你的理论,或是否存在其他解释
- 验证数据解读:阅读追踪信息、日志或查询输出时,确认你的解读是否正确
- 挑战修复方案:在提出代码变更前,询问该修复是否真正解决根本原因,还是仅掩盖症状
- 交叉检查复杂逻辑:当问题涉及多个系统(前端+API+数据库+权限)时,获取对交互逻辑的独立解读
- 证明结论合理性:当你准备告知用户“X是原因”时,确保另一个视角同意——或明确分歧
Guidelines
指南
- Set a 5-minute timeout: Codex can take a while to respond. When running via the Bash tool, set the Bash timeout to 300000ms (5 minutes) to avoid premature termination. Do NOT pass
codex execto--timeoutitself — it doesn't support that flag.codex exec - Be specific: Include the actual error, trace output, or code snippet — not just a vague description
- Ask for validation, not just answers: "Does this evidence support my conclusion that X?" is better than "What's wrong?"
- Include your current hypothesis: Let the other agent confirm or challenge it, rather than starting from scratch
- Include what you've already ruled out: This avoids duplicate investigation and focuses the consultation
- Always report back to the user: When you consult another agent, tell the user you did so. Summarize what you asked, what the other agent found, and whether you agree with their assessment. If there's a disagreement, present both perspectives and the supporting evidence for each. The user should never be unaware that another agent was consulted.
- 设置5分钟超时:Codex响应可能较慢。通过Bash工具运行时,将Bash超时设置为300000ms(5分钟),避免提前终止。请勿向
codex exec本身传递codex exec参数——该工具不支持此标志。--timeout - 具体化问题:包含实际错误、追踪输出或代码片段——而非模糊描述
- 寻求验证而非答案:“此证据是否支持我关于X的结论?”比“出了什么问题?”更好
- 包含当前假设:让其他Agent确认或挑战你的假设,而非从头开始
- 说明已排除的可能性:避免重复调查,聚焦咨询方向
- 始终向用户反馈:当你咨询其他Agent时,告知用户。总结你的问题、其他Agent的发现,以及你是否同意其评估。若存在分歧,呈现两种观点及各自的支撑证据。用户不应被隐瞒咨询其他Agent的行为。
Test User Credentials
测试用户凭证
For testing authenticated flows:
- Email: demo@lightdash.com
- Password: demo_password!
用于测试认证流程:
- 邮箱: demo@lightdash.com
- 密码: demo_password!
API Access (Personal Access Token)
API访问(个人访问令牌)
Prefer this method over using via Chrome DevTools MCP for API calls. with the PAT is faster, more reliable, and doesn't require a browser session or page context. Reserve browser MCP tools for UI interaction and visual debugging only.
fetch()curlA dev PAT is auto-provisioned by the seed data. Use it for direct API calls without browser login:
bash
undefined优先使用此方法通过Chrome DevTools MCP调用API,而非。 使用PAT的调用更快、更可靠,无需浏览器会话或页面上下文。仅在UI交互和可视化调试时使用浏览器MCP工具。
fetch()curl开发环境的PAT由种子数据自动配置。使用它直接调用API,无需浏览器登录:
bash
undefinedSource the env file to get LDPAT and LIGHTDASH_API_URL
加载环境文件获取LDPAT和LIGHTDASH_API_URL
source .env.development.local
source .env.development.local
Example: list projects
示例:列出项目
curl -s -H "Authorization: ApiKey $LDPAT" "$LIGHTDASH_API_URL/api/v1/org/projects" | jq
curl -s -H "Authorization: ApiKey $LDPAT" "$LIGHTDASH_API_URL/api/v1/org/projects" | jq
Example: get user info
示例:获取用户信息
curl -s -H "Authorization: ApiKey $LDPAT" "$LIGHTDASH_API_URL/api/v1/user" | jq
The token (`ldpat_deadbeefdeadbeefdeadbeefdeadbeef`) is defined in `SEED_PAT` from `@lightdash/common` and inserted during database seeding. It belongs to the admin user (`demo@lightdash.com`) and never expires.curl -s -H "Authorization: ApiKey $LDPAT" "$LIGHTDASH_API_URL/api/v1/user" | jq
令牌(`ldpat_deadbeefdeadbeefdeadbeefdeadbeef`)定义在`@lightdash/common`的`SEED_PAT`中,在数据库初始化时插入。它属于管理员用户(`demo@lightdash.com`)且永不过期。