-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstorage.html
More file actions
79 lines (77 loc) · 50.6 KB
/
Copy pathstorage.html
File metadata and controls
79 lines (77 loc) · 50.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<!DOCTYPE html>
<html lang="en-US" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Storage configuration | Piwi Dashboard</title>
<meta name="description" content="A modern dashboard for storing and visualising Playwright test results">
<meta name="generator" content="VitePress v1.6.4">
<link rel="preload stylesheet" href="/assets/style.BQLvV-8n.css" as="style">
<link rel="preload stylesheet" href="/vp-icons.css" as="style">
<script type="module" src="/assets/app.DZ6AppXx.js"></script>
<link rel="preload" href="/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
<link rel="modulepreload" href="/assets/chunks/theme.OFBQqYJb.js">
<link rel="modulepreload" href="/assets/chunks/framework.sV-XtlWr.js">
<link rel="modulepreload" href="/assets/storage.md.BcJ1SEnL.lean.js">
<meta property="og:type" content="website">
<meta property="og:title" content="Piwi Dashboard — A permanent home for your Playwright test results">
<meta property="og:description" content="Live dashboards, failure clustering, and flaky-test tracking for your whole team — self-hosted, no SaaS.">
<meta property="og:image" content="https://piwitests.github.io/og-image.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:url" content="https://piwitests.github.io">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Piwi Dashboard — A permanent home for your Playwright test results">
<meta name="twitter:description" content="Live dashboards, failure clustering, and flaky-test tracking for your whole team — self-hosted, no SaaS.">
<meta name="twitter:image" content="https://piwitests.github.io/og-image.png">
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
</head>
<body>
<div id="app"><div class="Layout" data-v-d8b57b2d><!--[--><!--]--><!--[--><span tabindex="-1" data-v-fcbfc0e0></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-fcbfc0e0>Skip to content</a><!--]--><!----><header class="VPNav" data-v-d8b57b2d data-v-7ad780c2><div class="VPNavBar" data-v-7ad780c2 data-v-9fd4d1dd><div class="wrapper" data-v-9fd4d1dd><div class="container" data-v-9fd4d1dd><div class="title" data-v-9fd4d1dd><div class="VPNavBarTitle has-sidebar" data-v-9fd4d1dd data-v-9f43907a><a class="title" href="/" data-v-9f43907a><!--[--><!--]--><!----><span data-v-9f43907a>Piwi Dashboard</span><!--[--><!--]--></a></div></div><div class="content" data-v-9fd4d1dd><div class="content-body" data-v-9fd4d1dd><!--[--><!--]--><div class="VPNavBarSearch search" data-v-9fd4d1dd><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><span class="vp-icon DocSearch-Search-Icon"></span><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-9fd4d1dd data-v-afb2845e><span id="main-nav-aria-label" class="visually-hidden" data-v-afb2845e> Main Navigation </span><!--[--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/" tabindex="0" data-v-afb2845e data-v-815115f5><!--[--><span data-v-815115f5>Home</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/getting-started.html" tabindex="0" data-v-afb2845e data-v-815115f5><!--[--><span data-v-815115f5>Getting started</span><!--]--></a><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/reporter.html" tabindex="0" data-v-afb2845e data-v-815115f5><!--[--><span data-v-815115f5>Reporter</span><!--]--></a><!--]--><!--[--><a class="VPLink link vp-external-link-icon VPNavBarMenuLink" href="https://piwitests.github.io/demo/docs" target="_blank" rel="noreferrer" tabindex="0" data-v-afb2845e data-v-815115f5><!--[--><span data-v-815115f5>API docs</span><!--]--></a><!--]--><!--[--><a class="VPLink link vp-external-link-icon VPNavBarMenuLink" href="https://piwitests.github.io/demo/" target="_blank" rel="noreferrer" tabindex="0" data-v-afb2845e data-v-815115f5><!--[--><span data-v-815115f5>Demo</span><!--]--></a><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-9fd4d1dd data-v-3f90c1a5><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-3f90c1a5 data-v-be9742d9 data-v-b4ccac88><span class="check" data-v-b4ccac88><span class="icon" data-v-b4ccac88><!--[--><span class="vpi-sun sun" data-v-be9742d9></span><span class="vpi-moon moon" data-v-be9742d9></span><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-9fd4d1dd data-v-ef6192dc data-v-e71e869c><!--[--><a class="VPSocialLink no-icon" href="https://github.com/PiwiTests/platform" aria-label="github" target="_blank" rel="noopener" data-v-e71e869c data-v-60a9a2d3><span class="vpi-social-github"></span></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-9fd4d1dd data-v-f953d92f data-v-bfe7971f><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-bfe7971f><span class="vpi-more-horizontal icon" data-v-bfe7971f></span></button><div class="menu" data-v-bfe7971f><div class="VPMenu" data-v-bfe7971f data-v-20ed86d6><!----><!--[--><!--[--><!----><div class="group" data-v-f953d92f><div class="item appearance" data-v-f953d92f><p class="label" data-v-f953d92f>Appearance</p><div class="appearance-action" data-v-f953d92f><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-f953d92f data-v-be9742d9 data-v-b4ccac88><span class="check" data-v-b4ccac88><span class="icon" data-v-b4ccac88><!--[--><span class="vpi-sun sun" data-v-be9742d9></span><span class="vpi-moon moon" data-v-be9742d9></span><!--]--></span></span></button></div></div></div><div class="group" data-v-f953d92f><div class="item social-links" data-v-f953d92f><div class="VPSocialLinks social-links-list" data-v-f953d92f data-v-e71e869c><!--[--><a class="VPSocialLink no-icon" href="https://github.com/PiwiTests/platform" aria-label="github" target="_blank" rel="noopener" data-v-e71e869c data-v-60a9a2d3><span class="vpi-social-github"></span></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-9fd4d1dd data-v-6bee1efd><span class="container" data-v-6bee1efd><span class="top" data-v-6bee1efd></span><span class="middle" data-v-6bee1efd></span><span class="bottom" data-v-6bee1efd></span></span></button></div></div></div></div><div class="divider" data-v-9fd4d1dd><div class="divider-line" data-v-9fd4d1dd></div></div></div><!----></header><div class="VPLocalNav has-sidebar empty" data-v-d8b57b2d data-v-2488c25a><div class="container" data-v-2488c25a><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-2488c25a><span class="vpi-align-left menu-icon" data-v-2488c25a></span><span class="menu-text" data-v-2488c25a>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-2488c25a data-v-6b867909><button data-v-6b867909>Return to top</button><!----></div></div></div><aside class="VPSidebar" data-v-d8b57b2d data-v-42c4c606><div class="curtain" data-v-42c4c606></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-42c4c606><span class="visually-hidden" id="sidebar-aria-label" data-v-42c4c606> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0" data-v-51288d80 data-v-0009425e><!----><div class="items" data-v-0009425e><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/getting-started.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Getting started</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/comparison.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Why Piwi? (comparison & FAQ)</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/ui-overview.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>UI overview</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/reporter.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Reporter</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/capture-fixtures.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Capture fixtures</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0" data-v-51288d80 data-v-0009425e><div class="item" role="button" tabindex="0" data-v-0009425e><div class="indicator" data-v-0009425e></div><h2 class="text" data-v-0009425e>Features</h2><!----></div><div class="items" data-v-0009425e><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/ai-diagnosis.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>AI diagnosis & clustering</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/flaky-tests.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Flaky tests & analytics</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/timeline-markers.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Timeline markers</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/notifications.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Notifications & alerts</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0 has-active" data-v-51288d80 data-v-0009425e><div class="item" role="button" tabindex="0" data-v-0009425e><div class="indicator" data-v-0009425e></div><h2 class="text" data-v-0009425e>Configuration</h2><!----></div><div class="items" data-v-0009425e><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/configuration.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Configuration reference</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/configuration/generator.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Configuration generator</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/authentication.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Authentication</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/storage.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Storage configuration</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/deployment.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Deployment</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0" data-v-51288d80 data-v-0009425e><div class="item" role="button" tabindex="0" data-v-0009425e><div class="indicator" data-v-0009425e></div><h2 class="text" data-v-0009425e>Integrate</h2><!----></div><div class="items" data-v-0009425e><!--[--><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link vp-external-link-icon link" href="https://piwitests.github.io/demo/docs" target="_blank" rel="noreferrer" data-v-0009425e><!--[--><p class="text" data-v-0009425e>API docs (interactive)</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/mcp.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>MCP server</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/ide-integration.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Open in IDE</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-0009425e data-v-0009425e><div class="item" data-v-0009425e><div class="indicator" data-v-0009425e></div><a class="VPLink link link" href="/backend-logs.html" data-v-0009425e><!--[--><p class="text" data-v-0009425e>Backend logs</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-d8b57b2d data-v-9a6c75ad><div class="VPDoc has-sidebar has-aside" data-v-9a6c75ad data-v-e6f2a212><!--[--><!--]--><div class="container" data-v-e6f2a212><div class="aside" data-v-e6f2a212><div class="aside-curtain" data-v-e6f2a212></div><div class="aside-container" data-v-e6f2a212><div class="aside-content" data-v-e6f2a212><div class="VPDocAside" data-v-e6f2a212 data-v-cb998dce><!--[--><!--]--><!--[--><!--]--><nav aria-labelledby="doc-outline-aria-label" class="VPDocAsideOutline" data-v-cb998dce data-v-f610f197><div class="content" data-v-f610f197><div class="outline-marker" data-v-f610f197></div><div aria-level="2" class="outline-title" id="doc-outline-aria-label" role="heading" data-v-f610f197>On this page</div><ul class="VPDocOutlineItem root" data-v-f610f197 data-v-53c99d69><!--[--><!--]--></ul></div></nav><!--[--><!--]--><div class="spacer" data-v-cb998dce></div><!--[--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-e6f2a212><div class="content-container" data-v-e6f2a212><!--[--><!--]--><main class="main" data-v-e6f2a212><div style="position:relative;" class="vp-doc _storage external-link-icon-enabled" data-v-e6f2a212><div><h1 id="storage-configuration" tabindex="-1">Storage configuration <a class="header-anchor" href="#storage-configuration" aria-label="Permalink to "Storage configuration""></a></h1><p>The dashboard supports two storage backends for test artifacts (HTML reports, trace files, etc.).</p><h2 id="local-storage-default" tabindex="-1">Local storage (default) <a class="header-anchor" href="#local-storage-default" aria-label="Permalink to "Local storage (default)""></a></h2><p>Files are stored in the <code>.data/storage/</code> directory relative to the application. No configuration is required.</p><p>To customize the path:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># In application/.env</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_STORAGE_TYPE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">local</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_STORAGE_PATH</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/custom/path/to/storage</span></span></code></pre></div><h2 id="s3-compatible-storage" tabindex="-1">S3-compatible storage <a class="header-anchor" href="#s3-compatible-storage" aria-label="Permalink to "S3-compatible storage""></a></h2><p>Any S3-compatible service can be used: AWS S3, MinIO, DigitalOcean Spaces, Cloudflare R2, and others.</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># In application/.env</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_STORAGE_TYPE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">s3</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_BUCKET</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">your-bucket-name</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_REGION</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">us-east-1</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_ACCESS_KEY_ID</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">your-access-key</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_SECRET_ACCESS_KEY</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">your-secret-key</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Optional: custom endpoint for S3-compatible services</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_ENDPOINT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">https://s3.example.com</span></span></code></pre></div><h3 id="aws-s3" tabindex="-1">AWS S3 <a class="header-anchor" href="#aws-s3" aria-label="Permalink to "AWS S3""></a></h3><p>Obtain credentials from <strong>AWS Console → IAM → Users → Create user → Create access key</strong>.</p><p>Minimum required IAM permissions:</p><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "Version"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"2012-10-17"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "Statement"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: [</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "Effect"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Allow"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "Action"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"s3:PutObject"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"s3:GetObject"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"s3:HeadObject"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">],</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> "Resource"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"arn:aws:s3:::your-bucket-name/*"</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> ]</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><h3 id="minio" tabindex="-1">MinIO <a class="header-anchor" href="#minio" aria-label="Permalink to "MinIO""></a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_STORAGE_TYPE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">s3</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_ENDPOINT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">http://localhost:9000</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_BUCKET</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">piwi-dashboard</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_REGION</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">us-east-1</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_ACCESS_KEY_ID</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">minioadmin</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_SECRET_ACCESS_KEY</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">minioadmin</span></span></code></pre></div><p>Path-style URLs are enabled automatically when <code>PIWI_S3_ENDPOINT</code> is set (as required by MinIO and most self-hosted S3-compatible services). Set <code>PIWI_S3_FORCE_PATH_STYLE=false</code> to override this behavior.</p><h3 id="digitalocean-spaces" tabindex="-1">DigitalOcean Spaces <a class="header-anchor" href="#digitalocean-spaces" aria-label="Permalink to "DigitalOcean Spaces""></a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_STORAGE_TYPE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">s3</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_ENDPOINT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">https://nyc3.digitaloceanspaces.com</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_BUCKET</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">your-space-name</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_REGION</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">nyc3</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_ACCESS_KEY_ID</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">your-spaces-key</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_SECRET_ACCESS_KEY</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">your-spaces-secret</span></span></code></pre></div><h3 id="cloudflare-r2" tabindex="-1">Cloudflare R2 <a class="header-anchor" href="#cloudflare-r2" aria-label="Permalink to "Cloudflare R2""></a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_STORAGE_TYPE</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">s3</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_ENDPOINT</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">https://[account-id</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">].r2.cloudflarestorage.com</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_BUCKET</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">your-bucket-name</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_REGION</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">auto</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_ACCESS_KEY_ID</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">your-r2-access-key</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_S3_SECRET_ACCESS_KEY</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">your-r2-secret-key</span></span></code></pre></div><h2 id="storage-management" tabindex="-1">Storage management <a class="header-anchor" href="#storage-management" aria-label="Permalink to "Storage management""></a></h2><p>The <strong>Settings › Storage</strong> page (<code>/settings/storage</code>) provides administrators with:</p><ul><li><strong>Statistics</strong> — total projects, test runs, unique test cases, traces, stored reports, aggregate report size, and actual on-disk storage size (local only).</li><li><strong>Cleanup</strong> — permanently delete all test runs older than a configurable number of days (7, 14, 30, 60, 90, 180, or 365 days). A confirmation dialog is shown before any data is deleted.</li></ul><p>You can also delete individual test runs:</p><ul><li>From the <strong>test run detail page</strong> — click the red <strong>Delete</strong> button in the page header.</li><li>From the <strong>project detail page</strong> — click the <strong>Delete</strong> button in the Actions column of the test runs table.</li></ul><h3 id="data-retention" tabindex="-1">Data retention <a class="header-anchor" href="#data-retention" aria-label="Permalink to "Data retention""></a></h3><p>A nightly sweep (03:17 server time) handles recurring cleanup:</p><ul><li><strong>Test-run pruning</strong> — deletes runs older than <code>PIWI_RETENTION_DAYS</code> days, including their files, traces, and reports. <strong>Off by default</strong>: deleting history is opt-in, so nothing is pruned until you set the variable.</li><li><strong>Notification outbox pruning</strong> — removes sent/failed delivery rows older than <code>PIWI_RETENTION_NOTIFICATION_DAYS</code> days (default 30).</li><li><strong>Diagnosis history capping</strong> — keeps the newest <code>PIWI_RETENTION_DIAGNOSIS_VERSIONS</code> versions per AI diagnosis (default 20).</li><li><strong>Orphan sweep</strong> — removes rows whose parent records were deleted by older versions.</li></ul><p>The manual <strong>Settings › Storage</strong> cleanup remains available for one-off bulk deletes and uses the same deletion logic.</p><h3 id="space-reclamation" tabindex="-1">Space reclamation <a class="header-anchor" href="#space-reclamation" aria-label="Permalink to "Space reclamation""></a></h3><p>Deleting runs removes rows and stored files, but giving the freed pages back to the filesystem depends on the backend:</p><ul><li><strong>SQLite</strong> — databases created by recent versions have <code>auto_vacuum=INCREMENTAL</code> enabled, so the cleanup endpoint reclaims space automatically. Databases created before that (where <code>PRAGMA auto_vacuum</code> reports <code>0</code>) need a one-off full rebuild: call the cleanup API with <code>{ "olderThanDays": ..., "vacuum": true }</code> to run a blocking <code>VACUUM</code> after the delete. Expect it to take a while on large databases.</li><li><strong>PostgreSQL</strong> — freed space is reused by PostgreSQL's autovacuum; no manual action is needed.</li></ul><h2 id="storage-architecture" tabindex="-1">Storage architecture <a class="header-anchor" href="#storage-architecture" aria-label="Permalink to "Storage architecture""></a></h2><p>The dashboard uses an abstraction layer that allows switching backends without any code changes. Files are stored using relative paths (e.g. <code>project-1/run-123/index.html</code>), making migration between backends straightforward.</p><h3 id="evidence-payload-deduplication" tabindex="-1">Evidence payload deduplication <a class="header-anchor" href="#evidence-payload-deduplication" aria-label="Permalink to "Evidence payload deduplication""></a></h3><p>Large failure evidence captured per execution — the page's ARIA snapshot, the failing test's source snippet, and its source stack frames — is stored content-addressed: each unique payload is written once per project (keyed by SHA-256) and executions reference it by id. A test that fails the same way across many runs, or across several browsers in one run, stores that evidence a single time instead of once per execution. Unreferenced payloads are garbage-collected when runs are deleted. Deduplication happens server-side at ingest, so it applies regardless of reporter version.</p><h2 id="database-storage" tabindex="-1">Database storage <a class="header-anchor" href="#database-storage" aria-label="Permalink to "Database storage""></a></h2><p>The dashboard supports two database backends: <strong>SQLite</strong> (default, zero-configuration) and <strong>PostgreSQL</strong> (for production multi-user deployments).</p><h3 id="sqlite-default" tabindex="-1">SQLite (default) <a class="header-anchor" href="#sqlite-default" aria-label="Permalink to "SQLite (default)""></a></h3><p>SQLite requires no configuration. The database file is created automatically at <code>.data/piwi.db</code>.</p><p>To customize the path, set the variable in <code>application/.env</code> (recommended, cross-platform), or pass it inline:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-dn8Zp" id="tab-lVOrvuP" checked><label data-title="Linux / macOS" for="tab-lVOrvuP">Linux / macOS</label><input type="radio" name="group-dn8Zp" id="tab-GbIJxFs"><label data-title="Windows (PowerShell)" for="tab-GbIJxFs">Windows (PowerShell)</label></div><div class="blocks"><div class="language-bash vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_DATABASE_PATH</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">/custom/path/database.db</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> app:dev</span></span></code></pre></div><div class="language-powershell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">powershell</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">$</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">env:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_DATABASE_PATH </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '/custom/path/database.db'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; npm run app:dev</span></span></code></pre></div></div></div><h3 id="postgresql" tabindex="-1">PostgreSQL <a class="header-anchor" href="#postgresql" aria-label="Permalink to "PostgreSQL""></a></h3><p>Set the <code>PIWI_DATABASE_URL</code> environment variable to switch to PostgreSQL (in <code>application/.env</code>, or inline):</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-R-zh2" id="tab-60WBkeO" checked><label data-title="Linux / macOS" for="tab-60WBkeO">Linux / macOS</label><input type="radio" name="group-R-zh2" id="tab-ItVWPbz"><label data-title="Windows (PowerShell)" for="tab-ItVWPbz">Windows (PowerShell)</label></div><div class="blocks"><div class="language-bash vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_DATABASE_URL</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">postgresql://user:password@localhost:5432/piwi_dashboard</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> app:dev</span></span></code></pre></div><div class="language-powershell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">powershell</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">$</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">env:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_DATABASE_URL </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'postgresql://user:password@localhost:5432/piwi_dashboard'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; npm run app:dev</span></span></code></pre></div></div></div><p>The dashboard creates all required tables automatically on startup via migrations.</p><h4 id="local-development-with-docker" tabindex="-1">Local development with Docker <a class="header-anchor" href="#local-development-with-docker" aria-label="Permalink to "Local development with Docker""></a></h4><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">docker</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -d</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -p</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 5432:5432</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -e</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> POSTGRES_USER=postgres</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -e</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> POSTGRES_PASSWORD=postgres</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -e</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> POSTGRES_DB=piwi_dashboard</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> postgres:16-alpine</span></span></code></pre></div><p>Then start the dashboard:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-gL6IS" id="tab-HymLyMS" checked><label data-title="Linux / macOS" for="tab-HymLyMS">Linux / macOS</label><input type="radio" name="group-gL6IS" id="tab-UMOYM1-"><label data-title="Windows (PowerShell)" for="tab-UMOYM1-">Windows (PowerShell)</label></div><div class="blocks"><div class="language-bash vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_DATABASE_URL</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">postgresql://postgres:postgres@localhost:5432/piwi_dashboard</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> app:dev</span></span></code></pre></div><div class="language-powershell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">powershell</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">$</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">env:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_DATABASE_URL </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'postgresql://postgres:postgres@localhost:5432/piwi_dashboard'</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; npm run app:dev</span></span></code></pre></div></div></div><h4 id="schema-changes-postgresql" tabindex="-1">Schema changes (PostgreSQL) <a class="header-anchor" href="#schema-changes-postgresql" aria-label="Permalink to "Schema changes (PostgreSQL)""></a></h4><p>To generate a new PostgreSQL migration after editing <code>schema.pg.ts</code>:</p><div class="vp-code-group vp-adaptive-theme"><div class="tabs"><input type="radio" name="group-rPkWp" id="tab-UEKCXRG" checked><label data-title="Linux / macOS" for="tab-UEKCXRG">Linux / macOS</label><input type="radio" name="group-rPkWp" id="tab-vtd_MZO"><label data-title="Windows (PowerShell)" for="tab-vtd_MZO">Windows (PowerShell)</label></div><div class="blocks"><div class="language-bash vp-adaptive-theme active"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_DATABASE_URL</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">postgresql://...</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> db:generate:pg</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> db:migrate:pg</span></span></code></pre></div><div class="language-powershell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">powershell</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">$</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">env:</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">PIWI_DATABASE_URL </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'postgresql://...'</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">npm run db:generate:pg</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">npm run db:migrate:pg</span></span></code></pre></div></div></div><table tabindex="0"><thead><tr><th>Script</th><th>Description</th></tr></thead><tbody><tr><td><code>npm run db:generate</code></td><td>Generate SQLite migration</td></tr><tr><td><code>npm run db:migrate</code></td><td>Apply SQLite migrations</td></tr><tr><td><code>npm run db:generate:pg</code></td><td>Generate PostgreSQL migration</td></tr><tr><td><code>npm run db:migrate:pg</code></td><td>Apply PostgreSQL migrations</td></tr><tr><td><code>npm run db:studio</code></td><td>Browse SQLite database</td></tr><tr><td><code>npm run db:studio:pg</code></td><td>Browse PostgreSQL database</td></tr></tbody></table><h3 id="schema-changes-sqlite" tabindex="-1">Schema changes (SQLite) <a class="header-anchor" href="#schema-changes-sqlite" aria-label="Permalink to "Schema changes (SQLite)""></a></h3><p>If you modify the database schema:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># 1. Edit application/server/database/schema.sqlite.ts</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># 2. Generate a new migration</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> db:generate</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># 3. Restart the application — migrations apply automatically on startup</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">npm</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> run</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> app:dev</span></span></code></pre></div><div class="warning custom-block"><p class="custom-block-title">WARNING</p><p>Never delete or modify existing migration files. Always generate new migrations for schema changes.</p></div></div></div></main><footer class="VPDocFooter" data-v-e6f2a212 data-v-1bcd8184><!--[--><!--]--><div class="edit-info" data-v-1bcd8184><div class="edit-link" data-v-1bcd8184><a class="VPLink link vp-external-link-icon no-icon edit-link-button" href="https://github.com/PiwiTests/platform/edit/main/docs/storage.md" target="_blank" rel="noreferrer" data-v-1bcd8184><!--[--><span class="vpi-square-pen edit-link-icon" data-v-1bcd8184></span> Edit this page on GitHub<!--]--></a></div><div class="last-updated" data-v-1bcd8184><p class="VPLastUpdated" data-v-1bcd8184 data-v-1bb0c8a8>Updated at: <time datetime="2026-07-21T11:53:55.000Z" data-v-1bb0c8a8></time></p></div></div><nav class="prev-next" aria-labelledby="doc-footer-aria-label" data-v-1bcd8184><span class="visually-hidden" id="doc-footer-aria-label" data-v-1bcd8184>Pager</span><div class="pager" data-v-1bcd8184><a class="VPLink link pager-link prev" href="/authentication.html" data-v-1bcd8184><!--[--><span class="desc" data-v-1bcd8184>Previous page</span><span class="title" data-v-1bcd8184>Authentication</span><!--]--></a></div><div class="pager" data-v-1bcd8184><a class="VPLink link pager-link next" href="/deployment.html" data-v-1bcd8184><!--[--><span class="desc" data-v-1bcd8184>Next page</span><span class="title" data-v-1bcd8184>Deployment</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><footer class="VPFooter has-sidebar" data-v-d8b57b2d data-v-566314d4><div class="container" data-v-566314d4><p class="message" data-v-566314d4>Released under the MIT License. Zero telemetry — Piwi never phones home.<br>Piwi Dashboard is not affiliated with, endorsed by, or connected to Microsoft Corporation. Playwright is a trademark of Microsoft.</p><p class="copyright" data-v-566314d4>Copyright © 2025-present Fabien Ménager</p></div></footer><!--[--><!--]--></div></div>
<script>window.__VP_HASH_MAP__=JSON.parse("{\"ai-diagnosis.md\":\"Cpw5oTwa\",\"authentication.md\":\"DN4OhJso\",\"backend-logs.md\":\"BMzT7wK8\",\"capture-fixtures.md\":\"R4-AaDfi\",\"comparison.md\":\"vHrC6lXe\",\"configuration.md\":\"DpBH5lnO\",\"configuration_generator.md\":\"mytTOhd6\",\"deployment.md\":\"IXm3Wesl\",\"flaky-tests.md\":\"Cjqnf2hV\",\"getting-started.md\":\"mpNpUg-D\",\"ide-integration.md\":\"BnhZA5og\",\"index.md\":\"XBHIPn01\",\"mcp.md\":\"DxD6p-XC\",\"notifications.md\":\"PHnGwD7j\",\"reporter.md\":\"DYC1D7m9\",\"storage.md\":\"BcJ1SEnL\",\"timeline-markers.md\":\"DTCSGURH\",\"ui-overview.md\":\"9HAv7tpO\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Piwi Dashboard\",\"description\":\"A modern dashboard for storing and visualising Playwright test results\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"outline\":\"deep\",\"search\":{\"provider\":\"local\"},\"nav\":[{\"text\":\"Home\",\"link\":\"/\"},{\"text\":\"Getting started\",\"link\":\"/getting-started\"},{\"text\":\"Reporter\",\"link\":\"/reporter\"},{\"text\":\"API docs\",\"link\":\"https://piwitests.github.io/demo/docs\"},{\"text\":\"Demo\",\"link\":\"https://piwitests.github.io/demo/\"}],\"sidebar\":[{\"text\":\"Getting started\",\"link\":\"/getting-started\"},{\"text\":\"Why Piwi? (comparison & FAQ)\",\"link\":\"/comparison\"},{\"text\":\"UI overview\",\"link\":\"/ui-overview\"},{\"text\":\"Reporter\",\"link\":\"/reporter\"},{\"text\":\"Capture fixtures\",\"link\":\"/capture-fixtures\"},{\"text\":\"Features\",\"items\":[{\"text\":\"AI diagnosis & clustering\",\"link\":\"/ai-diagnosis\"},{\"text\":\"Flaky tests & analytics\",\"link\":\"/flaky-tests\"},{\"text\":\"Timeline markers\",\"link\":\"/timeline-markers\"},{\"text\":\"Notifications & alerts\",\"link\":\"/notifications\"}]},{\"text\":\"Configuration\",\"items\":[{\"text\":\"Configuration reference\",\"link\":\"/configuration\"},{\"text\":\"Configuration generator\",\"link\":\"/configuration/generator\"},{\"text\":\"Authentication\",\"link\":\"/authentication\"},{\"text\":\"Storage configuration\",\"link\":\"/storage\"},{\"text\":\"Deployment\",\"link\":\"/deployment\"}]},{\"text\":\"Integrate\",\"items\":[{\"text\":\"API docs (interactive)\",\"link\":\"https://piwitests.github.io/demo/docs\"},{\"text\":\"MCP server\",\"link\":\"/mcp\"},{\"text\":\"Open in IDE\",\"link\":\"/ide-integration\"},{\"text\":\"Backend logs\",\"link\":\"/backend-logs\"}]}],\"editLink\":{\"pattern\":\"https://github.com/PiwiTests/platform/edit/main/docs/:path\",\"text\":\"Edit this page on GitHub\"},\"lastUpdated\":{\"text\":\"Updated at\",\"formatOptions\":{\"dateStyle\":\"full\",\"timeStyle\":\"medium\"}},\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://github.com/PiwiTests/platform\"}],\"externalLinkIcon\":true,\"footer\":{\"message\":\"Released under the MIT License. Zero telemetry — Piwi never phones home.<br>Piwi Dashboard is not affiliated with, endorsed by, or connected to Microsoft Corporation. Playwright is a trademark of Microsoft.\",\"copyright\":\"Copyright © 2025-present Fabien Ménager\"}},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
</body>
</html>