@rakay-technology/kraft 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +263 -0
- package/dist/bare-HL2GUYE2.js +27 -0
- package/dist/bowser-HNOTPGJO.js +2825 -0
- package/dist/chunk-3CJLKL6E.js +124 -0
- package/dist/chunk-3NQQXMDR.js +2098 -0
- package/dist/chunk-42WQABXM.js +439 -0
- package/dist/chunk-5GPXMTE4.js +25 -0
- package/dist/chunk-AJ4QZLZ2.js +1069 -0
- package/dist/chunk-AO252K7Z.js +137 -0
- package/dist/chunk-BQMFIXHI.js +975 -0
- package/dist/chunk-DM3PKWDC.js +2453 -0
- package/dist/chunk-DOD2BXHQ.js +1364 -0
- package/dist/chunk-DRK3MEDS.js +2870 -0
- package/dist/chunk-EW4PHKB2.js +13914 -0
- package/dist/chunk-HMJUFZK7.js +340 -0
- package/dist/chunk-I2TOOF2A.js +517 -0
- package/dist/chunk-I3DPMTSF.js +29 -0
- package/dist/chunk-JSCZT76F.js +2588 -0
- package/dist/chunk-MNV2QFHW.js +138 -0
- package/dist/chunk-MOLPYPVH.js +2529 -0
- package/dist/chunk-N4OALTFK.js +295 -0
- package/dist/chunk-OFXBNFNL.js +458 -0
- package/dist/chunk-ONKEYSMY.js +1388 -0
- package/dist/chunk-PDW4L3NV.js +17 -0
- package/dist/chunk-PNNXWA2A.js +1947 -0
- package/dist/chunk-PNRPKRJU.js +11105 -0
- package/dist/chunk-PVOWHIND.js +26781 -0
- package/dist/chunk-PXKCZB2I.js +46 -0
- package/dist/chunk-PZVKPCKE.js +475 -0
- package/dist/chunk-QWHBRY2K.js +4945 -0
- package/dist/chunk-RFOBMHQ7.js +338 -0
- package/dist/chunk-RHLNVZMS.js +28 -0
- package/dist/chunk-RVER2EOO.js +577 -0
- package/dist/chunk-S3QBGGVP.js +81 -0
- package/dist/chunk-TAML5WMA.js +198 -0
- package/dist/chunk-THTEUDBC.js +3188 -0
- package/dist/chunk-WYNM7L22.js +329 -0
- package/dist/chunk-XGCG4MD5.js +102 -0
- package/dist/chunk-XVKUFMIB.js +148 -0
- package/dist/chunk-XZYFZ6A5.js +50 -0
- package/dist/chunk-Y7PVJUXJ.js +2275 -0
- package/dist/chunk-YRSZPVMB.js +306 -0
- package/dist/chunk-YZUKHG3S.js +362 -0
- package/dist/chunk-ZVFS4LUA.js +116 -0
- package/dist/chunk-ZWLDLTJP.js +1417 -0
- package/dist/detect-676SNZK4.js +48 -0
- package/dist/dist-es-2YRDXMUU.js +73 -0
- package/dist/dist-es-CCVZEFRZ.js +91 -0
- package/dist/dist-es-EDUSMF6Q.js +488 -0
- package/dist/dist-es-IOH6G4GM.js +380 -0
- package/dist/dist-es-KWSMDPIP.js +26 -0
- package/dist/dist-es-UYDDOVZ3.js +173 -0
- package/dist/dist-es-XUOR4NQN.js +321 -0
- package/dist/docker-GOT3Q7DJ.js +41 -0
- package/dist/docker-edge-executor-VO6JHHW2.js +19 -0
- package/dist/edge-import-NFCHIW7G.js +50 -0
- package/dist/edge-preflight-QUJ757C6.js +45 -0
- package/dist/ensure-container-edge-Q7IZXHGM.js +38 -0
- package/dist/event-streams-TR4GAC53.js +46 -0
- package/dist/executor-GKXKN52K.js +42 -0
- package/dist/host-channel-preflight-Z6HYSPKO.js +48 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +9469 -0
- package/dist/loadSso-UGF4JMRK.js +581 -0
- package/dist/local-executor-OMMDKXCM.js +13 -0
- package/dist/nginx-VITTWZZU.js +42 -0
- package/dist/node-bootstrap.js +277 -0
- package/dist/node-entry.js +55 -0
- package/dist/noop-CLLJHCPL.js +11 -0
- package/dist/openresty-lua-6I3Z6PEQ.js +90 -0
- package/dist/privilege-UQAI2HV4.js +20 -0
- package/dist/server/engine/ChangeLog +2289 -0
- package/dist/server/engine/Documentations +5 -0
- package/dist/server/engine/LICENSE +674 -0
- package/dist/server/engine/README.md +34 -0
- package/dist/server/engine/conf/amavisd +150 -0
- package/dist/server/engine/conf/clamav +71 -0
- package/dist/server/engine/conf/core +632 -0
- package/dist/server/engine/conf/dovecot +151 -0
- package/dist/server/engine/conf/fail2ban +72 -0
- package/dist/server/engine/conf/global +698 -0
- package/dist/server/engine/conf/iredapd +52 -0
- package/dist/server/engine/conf/logwatch +28 -0
- package/dist/server/engine/conf/postfix +97 -0
- package/dist/server/engine/conf/postgresql +93 -0
- package/dist/server/engine/conf/spamassassin +39 -0
- package/dist/server/engine/dialog/config_via_dialog.sh +258 -0
- package/dist/server/engine/dialog/optional_components.sh +122 -0
- package/dist/server/engine/dialog/pgsql_config.sh +52 -0
- package/dist/server/engine/dialog/virtual_domain_config.sh +94 -0
- package/dist/server/engine/functions/amavisd.sh +267 -0
- package/dist/server/engine/functions/backend.sh +85 -0
- package/dist/server/engine/functions/clamav.sh +100 -0
- package/dist/server/engine/functions/cleanup.sh +393 -0
- package/dist/server/engine/functions/dovecot.sh +583 -0
- package/dist/server/engine/functions/fail2ban.sh +209 -0
- package/dist/server/engine/functions/iredapd.sh +356 -0
- package/dist/server/engine/functions/optional_components.sh +24 -0
- package/dist/server/engine/functions/packages.sh +522 -0
- package/dist/server/engine/functions/packages_freebsd.sh +179 -0
- package/dist/server/engine/functions/postfix.sh +457 -0
- package/dist/server/engine/functions/postgresql.sh +239 -0
- package/dist/server/engine/functions/spamassassin.sh +49 -0
- package/dist/server/engine/functions/system_accounts.sh +128 -0
- package/dist/server/engine/iRedMail.sh +144 -0
- package/dist/server/engine/pkgs/get_all.sh +338 -0
- package/dist/server/engine/pkgs/pkgs.freebsd.sha256 +3 -0
- package/dist/server/engine/pkgs/pkgs.openbsd.sha256 +6 -0
- package/dist/server/engine/pkgs/pkgs.sha256 +1 -0
- package/dist/server/engine/samples/amavisd/amavisd.conf +702 -0
- package/dist/server/engine/samples/amavisd/amavisd.mysql +278 -0
- package/dist/server/engine/samples/amavisd/amavisd.pgsql +253 -0
- package/dist/server/engine/samples/amavisd/amavisd.schema +942 -0
- package/dist/server/engine/samples/amavisd/default_spam_policy.sql +46 -0
- package/dist/server/engine/samples/dovecot/dovecot-2.4-mariadb.conf +758 -0
- package/dist/server/engine/samples/dovecot/dovecot-2.4-openldap.conf +767 -0
- package/dist/server/engine/samples/dovecot/dovecot-2.4-pgsql.conf +762 -0
- package/dist/server/engine/samples/dovecot/dovecot-last-login.conf +50 -0
- package/dist/server/engine/samples/dovecot/dovecot-ldap.conf +21 -0
- package/dist/server/engine/samples/dovecot/dovecot-share-folder.conf +22 -0
- package/dist/server/engine/samples/dovecot/dovecot-sql.conf +28 -0
- package/dist/server/engine/samples/dovecot/dovecot-used-quota.conf +13 -0
- package/dist/server/engine/samples/dovecot/dovecot.conf +484 -0
- package/dist/server/engine/samples/dovecot/dovecot.sieve +7 -0
- package/dist/server/engine/samples/dovecot/dovecot2-quota-warning.sh +38 -0
- package/dist/server/engine/samples/dovecot/sql/imap_share_folder.mysql +16 -0
- package/dist/server/engine/samples/dovecot/sql/last_login.mysql +12 -0
- package/dist/server/engine/samples/dovecot/sql/used_quota.mysql +26 -0
- package/dist/server/engine/samples/dovecot/systemd/override.conf +3 -0
- package/dist/server/engine/samples/fail2ban/action.d/banned_db.conf +9 -0
- package/dist/server/engine/samples/fail2ban/bin/fail2ban_banned_db +268 -0
- package/dist/server/engine/samples/fail2ban/fail2ban.local +17 -0
- package/dist/server/engine/samples/fail2ban/filter.d/dovecot.iredmail.conf +5 -0
- package/dist/server/engine/samples/fail2ban/filter.d/postfix-pregreet.iredmail.conf +16 -0
- package/dist/server/engine/samples/fail2ban/filter.d/postfix.iredmail.conf +18 -0
- package/dist/server/engine/samples/fail2ban/filter.d/roundcube.iredmail.conf +9 -0
- package/dist/server/engine/samples/fail2ban/jail.d/dovecot.local +8 -0
- package/dist/server/engine/samples/fail2ban/jail.d/nginx-http-auth.local +8 -0
- package/dist/server/engine/samples/fail2ban/jail.d/postfix-pregreet.local +9 -0
- package/dist/server/engine/samples/fail2ban/jail.d/postfix.local +8 -0
- package/dist/server/engine/samples/fail2ban/jail.d/roundcube.local +9 -0
- package/dist/server/engine/samples/fail2ban/jail.d/sogo.local +8 -0
- package/dist/server/engine/samples/fail2ban/jail.d/sshd.local +11 -0
- package/dist/server/engine/samples/fail2ban/jail.local +6 -0
- package/dist/server/engine/samples/fail2ban/openbsd/rc +27 -0
- package/dist/server/engine/samples/fail2ban/sql/fail2ban.mysql +49 -0
- package/dist/server/engine/samples/fail2ban/sql/fail2ban.pgsql +48 -0
- package/dist/server/engine/samples/firewall/firewalld/services/ssh.xml +6 -0
- package/dist/server/engine/samples/firewall/firewalld/zones/iredmail.xml +15 -0
- package/dist/server/engine/samples/firewall/iptables/ip6tables.init.debian +362 -0
- package/dist/server/engine/samples/firewall/iptables/ip6tables.rules +53 -0
- package/dist/server/engine/samples/firewall/iptables/iptables.init.debian +363 -0
- package/dist/server/engine/samples/firewall/iptables/iptables.rules +54 -0
- package/dist/server/engine/samples/firewall/nftables.conf +58 -0
- package/dist/server/engine/samples/freebsd/newsyslog.conf.d/dovecot.conf +3 -0
- package/dist/server/engine/samples/freebsd/newsyslog.conf.d/iredapd.conf +1 -0
- package/dist/server/engine/samples/freebsd/newsyslog.conf.d/mlmmjadmin.conf +1 -0
- package/dist/server/engine/samples/freebsd/newsyslog.conf.d/php-fpm.conf +2 -0
- package/dist/server/engine/samples/freebsd/newsyslog.conf.d/slapd.conf +1 -0
- package/dist/server/engine/samples/freebsd/syslog.d/dovecot.conf +2 -0
- package/dist/server/engine/samples/freebsd/syslog.d/fail2ban.conf +2 -0
- package/dist/server/engine/samples/freebsd/syslog.d/iredapd.conf +2 -0
- package/dist/server/engine/samples/freebsd/syslog.d/mlmmjadmin.conf +2 -0
- package/dist/server/engine/samples/freebsd/syslog.d/php-fpm.conf +2 -0
- package/dist/server/engine/samples/freebsd/syslog.d/slapd.conf +2 -0
- package/dist/server/engine/samples/iredmail/iredmail.mysql +491 -0
- package/dist/server/engine/samples/iredmail/iredmail.pgsql +465 -0
- package/dist/server/engine/samples/iredmail/iredmail.schema +456 -0
- package/dist/server/engine/samples/iredmail/used_quota_triggers_dovecot_2.3.pgsql +40 -0
- package/dist/server/engine/samples/iredmail/used_quota_triggers_dovecot_2.4.pgsql +18 -0
- package/dist/server/engine/samples/logrotate/dovecot +13 -0
- package/dist/server/engine/samples/logrotate/iredapd +13 -0
- package/dist/server/engine/samples/logrotate/mlmmjadmin +13 -0
- package/dist/server/engine/samples/logrotate/openldap +19 -0
- package/dist/server/engine/samples/logrotate/php-fpm +13 -0
- package/dist/server/engine/samples/openbsd/ldapd.conf +58 -0
- package/dist/server/engine/samples/openbsd/pf.conf +28 -0
- package/dist/server/engine/samples/postfix/command_filter.pcre +3 -0
- package/dist/server/engine/samples/postfix/freebsd/mailer.conf +9 -0
- package/dist/server/engine/samples/postfix/helo_access.pcre +180 -0
- package/dist/server/engine/samples/postfix/ldap/catchall_maps.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/recipient_bcc_maps_domain.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/recipient_bcc_maps_user.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/relay_domains.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/sender_bcc_maps_domain.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/sender_bcc_maps_user.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/sender_dependent_relayhost_maps_domain.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/sender_dependent_relayhost_maps_user.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/sender_login_maps.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/transport_maps_domain.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/transport_maps_user.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/virtual_alias_maps.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/virtual_group_maps.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/virtual_group_members_maps.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/virtual_mailbox_domains.cf +11 -0
- package/dist/server/engine/samples/postfix/ldap/virtual_mailbox_maps.cf +12 -0
- package/dist/server/engine/samples/postfix/main.cf +282 -0
- package/dist/server/engine/samples/postfix/main.cf.amavisd +7 -0
- package/dist/server/engine/samples/postfix/main.cf.dovecot +8 -0
- package/dist/server/engine/samples/postfix/main.cf.ldap +39 -0
- package/dist/server/engine/samples/postfix/main.cf.mlmmj +5 -0
- package/dist/server/engine/samples/postfix/main.cf.mysql +39 -0
- package/dist/server/engine/samples/postfix/main.cf.pgsql +39 -0
- package/dist/server/engine/samples/postfix/main.cf.postscreen +30 -0
- package/dist/server/engine/samples/postfix/master.cf +101 -0
- package/dist/server/engine/samples/postfix/mysql/catchall_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/domain_alias_catchall_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/domain_alias_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/recipient_bcc_maps_domain.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/recipient_bcc_maps_user.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/relay_domains.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/sender_bcc_maps_domain.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/sender_bcc_maps_user.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/sender_dependent_relayhost_maps.cf +6 -0
- package/dist/server/engine/samples/postfix/mysql/sender_login_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/transport_maps_domain.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/transport_maps_maillist.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/transport_maps_user.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/virtual_alias_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/virtual_mailbox_domains.cf +5 -0
- package/dist/server/engine/samples/postfix/mysql/virtual_mailbox_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/catchall_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/domain_alias_catchall_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/domain_alias_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/recipient_bcc_maps_domain.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/recipient_bcc_maps_user.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/relay_domains.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/sender_bcc_maps_domain.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/sender_bcc_maps_user.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/sender_dependent_relayhost_maps.cf +6 -0
- package/dist/server/engine/samples/postfix/pgsql/sender_login_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/transport_maps_domain.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/transport_maps_maillist.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/transport_maps_user.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/virtual_alias_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/virtual_mailbox_domains.cf +5 -0
- package/dist/server/engine/samples/postfix/pgsql/virtual_mailbox_maps.cf +5 -0
- package/dist/server/engine/samples/postfix/postscreen_access.cidr +6 -0
- package/dist/server/engine/samples/postgresql/sql/add_first_domain_and_user.sql +34 -0
- package/dist/server/engine/samples/postgresql/sql/grant_permissions.sql +14 -0
- package/dist/server/engine/samples/postgresql/sql/init_vmail_db.sql +15 -0
- package/dist/server/engine/samples/rsyslog.d/1-iredmail-dovecot.conf +23 -0
- package/dist/server/engine/samples/rsyslog.d/1-iredmail-fail2ban.conf +2 -0
- package/dist/server/engine/samples/rsyslog.d/1-iredmail-iredapd.conf +12 -0
- package/dist/server/engine/samples/rsyslog.d/1-iredmail-mlmmjadmin.conf +12 -0
- package/dist/server/engine/samples/rsyslog.d/1-iredmail-openldap.conf +2 -0
- package/dist/server/engine/samples/rsyslog.d/1-iredmail-phpfpm.conf +3 -0
- package/dist/server/engine/samples/spamassassin/local.cf +186 -0
- package/dist/server/engine/samples/spamassassin/razor.conf +1 -0
- package/dist/server/engine/samples/systemd/clamd.service.d/override.conf +2 -0
- package/dist/server/engine/samples/systemd/mariadb.service.d/override.conf +3 -0
- package/dist/server/engine/samples/systemd/slapd.service.d/override.conf +6 -0
- package/dist/server/engine/samples/yum/CentOS-Linux-AppStream.repo +6 -0
- package/dist/server/engine/samples/yum/CentOS-Linux-PowerTools.repo +6 -0
- package/dist/server/engine/samples/yum/CentOS-Stream-AppStream.repo +7 -0
- package/dist/server/engine/samples/yum/CentOS-Stream-PowerTools.repo +7 -0
- package/dist/server/engine/samples/yum/symas-openldap.repo +6 -0
- package/dist/server/engine/tools/add_enabled_service.py +60 -0
- package/dist/server/engine/tools/backup_mysql.sh +238 -0
- package/dist/server/engine/tools/backup_openldap.sh +230 -0
- package/dist/server/engine/tools/backup_pgsql.sh +217 -0
- package/dist/server/engine/tools/backup_sogo.sh +156 -0
- package/dist/server/engine/tools/create_mail_user_OpenLDAP.py +335 -0
- package/dist/server/engine/tools/create_mail_user_OpenLDAP.sh +287 -0
- package/dist/server/engine/tools/create_mail_user_SQL.sh +127 -0
- package/dist/server/engine/tools/enable_postscreen.sh +144 -0
- package/dist/server/engine/tools/fail2ban_unban_ip.sh +39 -0
- package/dist/server/engine/tools/find_sasl_login_ip.sh +20 -0
- package/dist/server/engine/tools/find_top_sasl_usernames.sh +28 -0
- package/dist/server/engine/tools/generate_ssl_keys.sh +85 -0
- package/dist/server/engine/tools/kill_high_cpu_sogo_process.sh +32 -0
- package/dist/server/engine/tools/ldap_assign_user_to_groups.py +151 -0
- package/dist/server/engine/tools/ldap_move_members_to_another_group.py +129 -0
- package/dist/server/engine/tools/migrate_sql_alias_table.py +177 -0
- package/dist/server/engine/update/0.9.8/amavisd.mysql +29 -0
- package/dist/server/engine/update/0.9.8/amavisd.pgsql +39 -0
- package/dist/server/engine/update/0.9.8/iredmail.mysql +53 -0
- package/dist/server/engine/update/0.9.8/iredmail.pgsql +61 -0
- package/dist/server/engine/update/0.9.9/iredmail.mysql +2 -0
- package/dist/server/engine/update/0.9.9/iredmail.pgsql +2 -0
- package/dist/server/engine/update/1.0/iredmail.mysql +2 -0
- package/dist/server/engine/update/1.0/iredmail.pgsql +2 -0
- package/dist/server/engine/update/1.2/last_login.mysql +16 -0
- package/dist/server/engine/update/1.4.0/iredmail.mysql +22 -0
- package/dist/server/engine/update/1.4.0/iredmail.pgsql +20 -0
- package/dist/server/engine/update/1.4.1/iredmail.mysql +3 -0
- package/dist/server/engine/update/1.4.1/iredmail.pgsql +3 -0
- package/dist/server/engine/update/1.4.1/sogo.mysql +11 -0
- package/dist/server/engine/update/1.4.1/sogo.pgsql +30 -0
- package/dist/server/engine/update/1.4.1/update-ldap.py +66 -0
- package/dist/server/engine/update/1.4.2/iredmail.mysql +9 -0
- package/dist/server/engine/update/1.4.2/iredmail.pgsql +9 -0
- package/dist/server/engine/update/1.4.2/sogo.pgsql +30 -0
- package/dist/server/engine/update/1.6.0/sogo_view.pgsql +27 -0
- package/dist/server/engine/update/1.6.3/iredmail.mysql +1 -0
- package/dist/server/engine/update/1.7.0/fail2ban.mysql +11 -0
- package/dist/server/engine/update/1.7.0/fail2ban.pgsql +12 -0
- package/dist/server/engine/update/1.7.1/amavisd.mysql +1 -0
- package/dist/server/engine/update/1.7.2/vmail.mysql +30 -0
- package/dist/server/engine/update/1.7.3/deleted_mailboxes.mysql +43 -0
- package/dist/server/engine/update/1.7.3/iredadmin.mysql +26 -0
- package/dist/server/engine/update/1.7.3/vmail.mysql +79 -0
- package/dist/server/engine/update/1.7.3/vmail.pgsql +9 -0
- package/dist/server/engine/update/README.md +1 -0
- package/dist/server/engine/update/ldap/README.md +39 -0
- package/dist/server/engine/update/ldap/update-ldap-dovecot-2.3.py +69 -0
- package/dist/server/index.js +349016 -0
- package/dist/server/lua/geo_country.lua +127 -0
- package/dist/server/lua/maxminddb.lua +403 -0
- package/dist/server/lua/mgmt_api.lua +654 -0
- package/dist/server/lua/pipe_stream.lua +103 -0
- package/dist/server/lua/rules_guard.lua +132 -0
- package/dist/server/lua/rules_lib.lua +176 -0
- package/dist/server/lua/site_logger.lua +405 -0
- package/dist/server/lua/webhook_handler.lua +126 -0
- package/dist/server/migrations/0000_init.sql +666 -0
- package/dist/server/migrations/0001_brief_tomorrow_man.sql +47 -0
- package/dist/server/migrations/0002_funny_dazzler.sql +2 -0
- package/dist/server/migrations/0003_third_killer_shrike.sql +1 -0
- package/dist/server/migrations/0004_session_active_org_not_null.sql +10 -0
- package/dist/server/migrations/0005_warm_amazoness.sql +3 -0
- package/dist/server/migrations/0006_lumpy_joystick.sql +1 -0
- package/dist/server/migrations/0007_outgoing_maginty.sql +2 -0
- package/dist/server/migrations/0008_frozen_cutover.sql +3 -0
- package/dist/server/migrations/0009_credits_billing.sql +142 -0
- package/dist/server/migrations/0010_credit_grant_dedupe.sql +14 -0
- package/dist/server/migrations/0011_remove_credit_ledger.sql +23 -0
- package/dist/server/migrations/0012_smart_deploys_and_git_rollback.sql +81 -0
- package/dist/server/migrations/0013_fix_check_run_rollup_unique.sql +38 -0
- package/dist/server/migrations/0014_default_rollback_git.sql +9 -0
- package/dist/server/migrations/0015_billing_idempotency_grants.sql +41 -0
- package/dist/server/migrations/0016_github_auth_high_findings.sql +30 -0
- package/dist/server/migrations/0017_spooky_rumiko_fujikawa.sql +6 -0
- package/dist/server/migrations/0018_calm_shatterstar.sql +1 -0
- package/dist/server/migrations/0019_rename_workspace_install_to_prepare.sql +1 -0
- package/dist/server/migrations/0020_uneven_the_renegades.sql +13 -0
- package/dist/server/migrations/0021_shiny_firestar.sql +2 -0
- package/dist/server/migrations/0022_version_on_success_backfill.sql +6 -0
- package/dist/server/migrations/0023_productive_gorilla_man.sql +17 -0
- package/dist/server/migrations/0024_sleepy_peter_quill.sql +2 -0
- package/dist/server/migrations/0025_smooth_blue_shield.sql +1 -0
- package/dist/server/migrations/0026_mail_backup_source.sql +11 -0
- package/dist/server/migrations/0027_opposite_anthem.sql +6 -0
- package/dist/server/migrations/0028_stale_rogue.sql +18 -0
- package/dist/server/migrations/0029_bouncy_loners.sql +16 -0
- package/dist/server/migrations/0030_bright_darkstar.sql +6 -0
- package/dist/server/migrations/0031_conscious_catseye.sql +13 -0
- package/dist/server/migrations/0032_wet_mimic.sql +51 -0
- package/dist/server/migrations/0033_eminent_molly_hayes.sql +2 -0
- package/dist/server/migrations/0034_nervous_surge.sql +1 -0
- package/dist/server/migrations/0035_thankful_morgan_stark.sql +1 -0
- package/dist/server/migrations/0036_gorgeous_scalphunter.sql +17 -0
- package/dist/server/migrations/0037_clever_makkari.sql +28 -0
- package/dist/server/migrations/0038_young_magneto.sql +1 -0
- package/dist/server/migrations/0039_secret_lady_ursula.sql +15 -0
- package/dist/server/migrations/0040_sharp_red_wolf.sql +16 -0
- package/dist/server/migrations/0041_round_spyke.sql +4 -0
- package/dist/server/migrations/0042_dapper_havok.sql +1 -0
- package/dist/server/migrations/0043_fast_sharon_ventura.sql +15 -0
- package/dist/server/migrations/0044_amused_shape.sql +8 -0
- package/dist/server/migrations/0045_amusing_korath.sql +1 -0
- package/dist/server/migrations/0046_white_harrier.sql +35 -0
- package/dist/server/migrations/0047_sloppy_strong_guy.sql +2 -0
- package/dist/server/migrations/0048_funny_emma_frost.sql +2 -0
- package/dist/server/migrations/0049_nappy_piledriver.sql +3 -0
- package/dist/server/migrations/0050_add_service_deployment_image_digest.sql +1 -0
- package/dist/server/migrations/0051_add_update_status.sql +19 -0
- package/dist/server/migrations/0052_add_notice_target.sql +2 -0
- package/dist/server/migrations/0053_colossal_sandman.sql +14 -0
- package/dist/server/migrations/0054_add_instance_smtp.sql +5 -0
- package/dist/server/migrations/0055_rainy_klaw.sql +22 -0
- package/dist/server/migrations/0056_moaning_daredevil.sql +2 -0
- package/dist/server/migrations/0057_complete_prism.sql +18 -0
- package/dist/server/migrations/0058_add_server_is_local.sql +1 -0
- package/dist/server/migrations/0059_legal_fixer.sql +18 -0
- package/dist/server/migrations/0060_add_route_strategy_host_port.sql +3 -0
- package/dist/server/migrations/0061_notification_default_multi_kind.sql +3 -0
- package/dist/server/migrations/0062_add_incoming_webhook.sql +21 -0
- package/dist/server/migrations/0063_add_migration_logs.sql +1 -0
- package/dist/server/migrations/0064_add_migration_partial.sql +2 -0
- package/dist/server/migrations/0065_custom_app_template.sql +14 -0
- package/dist/server/migrations/0066_ensure_migration_partial_columns.sql +2 -0
- package/dist/server/migrations/0067_webhook_delivery.sql +28 -0
- package/dist/server/migrations/0068_add_migration_target_volumes.sql +1 -0
- package/dist/server/migrations/0069_add_project_composite_routes.sql +1 -0
- package/dist/server/migrations/0070_forward_git_to_server.sql +1 -0
- package/dist/server/migrations/0071_gh_device_token.sql +3 -0
- package/dist/server/migrations/0072_gh_device_token_method.sql +1 -0
- package/dist/server/migrations/0073_project_volumes_object_storage.sql +3 -0
- package/dist/server/migrations/0074_project_compose_path.sql +1 -0
- package/dist/server/migrations/0075_service_command_argv.sql +1 -0
- package/dist/server/migrations/0076_rollback_retention.sql +17 -0
- package/dist/server/migrations/0077_domain_redirect.sql +13 -0
- package/dist/server/migrations/0078_grant_source_scope.sql +30 -0
- package/dist/server/migrations/0079_project_readiness.sql +18 -0
- package/dist/server/migrations/0080_deployment_error_classification.sql +26 -0
- package/dist/server/migrations/0081_project_readiness_repair.sql +34 -0
- package/dist/server/migrations/0082_edge_target_verification.sql +39 -0
- package/dist/server/migrations/0083_service_incident.sql +84 -0
- package/dist/server/migrations/0084_analytics_daily_rollup.sql +72 -0
- package/dist/server/migrations/0085_resource_usage.sql +68 -0
- package/dist/server/migrations/0086_remote_infra_updates.sql +41 -0
- package/dist/server/migrations/0087_server_container_version_columns.sql +17 -0
- package/dist/server/migrations/0088_audit_source_and_settings.sql +27 -0
- package/dist/server/migrations/0089_auto_scan_infra.sql +7 -0
- package/dist/server/migrations/0090_project_collect_paths.sql +18 -0
- package/dist/server/migrations/0091_project_server_id.sql +26 -0
- package/dist/server/migrations/0092_project_internal_alias.sql +13 -0
- package/dist/server/migrations/0093_service_incident_org_index.sql +13 -0
- package/dist/server/migrations/0094_backup_restore_meta.sql +15 -0
- package/dist/server/migrations/0095_backup_restore_cancel.sql +19 -0
- package/dist/server/migrations/0096_backup_policy_retention_defaults.sql +20 -0
- package/dist/server/migrations/0097_update_status_upstream_only.sql +35 -0
- package/dist/server/migrations/0098_instance_product_mode.sql +12 -0
- package/dist/server/migrations/0099_mail_webmail_project.sql +24 -0
- package/dist/server/migrations/0100_server_ssh_private_key.sql +11 -0
- package/dist/server/migrations/0101_mail_resume_step.sql +12 -0
- package/dist/server/migrations/0102_project_workload_axes.sql +19 -0
- package/dist/server/migrations/0103_dns_credential.sql +41 -0
- package/dist/server/migrations/0104_instance_host_control.sql +15 -0
- package/dist/server/migrations/0105_mail_inbound_rules.sql +80 -0
- package/dist/server/migrations/0106_mcp_call_tracking.sql +23 -0
- package/dist/server/migrations/0107_build_minute_metering_indexes.sql +20 -0
- package/dist/server/migrations/0108_credential.sql +68 -0
- package/dist/server/migrations/0109_service_build_args.sql +9 -0
- package/dist/server/migrations/0110_service_deployment_host_ports.sql +18 -0
- package/dist/server/migrations/0111_host_port_claim.sql +381 -0
- package/dist/server/migrations/0112_backup_run_execution_lease.sql +12 -0
- package/dist/server/migrations/0113_docker_migration_execution_lease.sql +11 -0
- package/dist/server/migrations/0114_build_session_execution_lease_index.sql +6 -0
- package/dist/server/migrations/0115_orphan_target_key.sql +3 -0
- package/dist/server/migrations/0116_domain_ssl_challenge.sql +2 -0
- package/dist/server/migrations/0117_github_installation_workspace_scope.sql +24 -0
- package/dist/server/migrations/0118_git_sources.sql +66 -0
- package/dist/server/migrations/0119_backup_run_batch.sql +8 -0
- package/dist/server/migrations/0120_domain_primary_unique.sql +24 -0
- package/dist/server/migrations/0121_host_port_claim_overlap.sql +14 -0
- package/dist/server/migrations/0122_data_transfer_staging.sql +45 -0
- package/dist/server/migrations/0123_drop_cloud_infra.sql +7 -0
- package/dist/server/migrations/0124_mail_dmarc_report.sql +23 -0
- package/dist/server/migrations/0125_server_security_snapshot.sql +22 -0
- package/dist/server/migrations/meta/0000_snapshot.json +4848 -0
- package/dist/server/migrations/meta/0001_snapshot.json +4991 -0
- package/dist/server/migrations/meta/0002_snapshot.json +5013 -0
- package/dist/server/migrations/meta/0003_snapshot.json +5020 -0
- package/dist/server/migrations/meta/0004_snapshot.json +5020 -0
- package/dist/server/migrations/meta/0005_snapshot.json +5039 -0
- package/dist/server/migrations/meta/0006_snapshot.json +5045 -0
- package/dist/server/migrations/meta/0007_snapshot.json +5057 -0
- package/dist/server/migrations/meta/0016_snapshot.json +6053 -0
- package/dist/server/migrations/meta/0017_snapshot.json +6091 -0
- package/dist/server/migrations/meta/0018_snapshot.json +6098 -0
- package/dist/server/migrations/meta/0019_snapshot.json +6098 -0
- package/dist/server/migrations/meta/0020_snapshot.json +6201 -0
- package/dist/server/migrations/meta/0021_snapshot.json +6213 -0
- package/dist/server/migrations/meta/0022_snapshot.json +6213 -0
- package/dist/server/migrations/meta/0023_snapshot.json +6331 -0
- package/dist/server/migrations/meta/0024_snapshot.json +6343 -0
- package/dist/server/migrations/meta/0025_snapshot.json +6350 -0
- package/dist/server/migrations/meta/0026_snapshot.json +6440 -0
- package/dist/server/migrations/meta/0027_snapshot.json +6447 -0
- package/dist/server/migrations/meta/0028_snapshot.json +6581 -0
- package/dist/server/migrations/meta/0029_snapshot.json +6710 -0
- package/dist/server/migrations/meta/0030_snapshot.json +6748 -0
- package/dist/server/migrations/meta/0031_snapshot.json +6859 -0
- package/dist/server/migrations/meta/0032_snapshot.json +7222 -0
- package/dist/server/migrations/meta/0033_snapshot.json +7249 -0
- package/dist/server/migrations/meta/0034_snapshot.json +7255 -0
- package/dist/server/migrations/meta/0035_snapshot.json +7262 -0
- package/dist/server/migrations/meta/0036_snapshot.json +7392 -0
- package/dist/server/migrations/meta/0037_snapshot.json +7602 -0
- package/dist/server/migrations/meta/0038_snapshot.json +7609 -0
- package/dist/server/migrations/meta/0039_snapshot.json +7714 -0
- package/dist/server/migrations/meta/0040_snapshot.json +7820 -0
- package/dist/server/migrations/meta/0041_snapshot.json +7833 -0
- package/dist/server/migrations/meta/0042_snapshot.json +7839 -0
- package/dist/server/migrations/meta/0043_snapshot.json +7938 -0
- package/dist/server/migrations/meta/0044_snapshot.json +7982 -0
- package/dist/server/migrations/meta/0045_snapshot.json +7989 -0
- package/dist/server/migrations/meta/0046_snapshot.json +8263 -0
- package/dist/server/migrations/meta/0047_snapshot.json +8275 -0
- package/dist/server/migrations/meta/0048_snapshot.json +8289 -0
- package/dist/server/migrations/meta/0049_snapshot.json +8308 -0
- package/dist/server/migrations/meta/0050_snapshot.json +8314 -0
- package/dist/server/migrations/meta/0051_snapshot.json +8460 -0
- package/dist/server/migrations/meta/0052_snapshot.json +8472 -0
- package/dist/server/migrations/meta/0053_snapshot.json +8556 -0
- package/dist/server/migrations/meta/0054_snapshot.json +8586 -0
- package/dist/server/migrations/meta/0055_snapshot.json +8756 -0
- package/dist/server/migrations/meta/0056_snapshot.json +8777 -0
- package/dist/server/migrations/meta/0057_snapshot.json +8904 -0
- package/dist/server/migrations/meta/0058_snapshot.json +8911 -0
- package/dist/server/migrations/meta/0059_snapshot.json +9061 -0
- package/dist/server/migrations/meta/0060_snapshot.json +9081 -0
- package/dist/server/migrations/meta/_journal.json +888 -0
- package/dist/server/pglite/pglite.data +0 -0
- package/dist/server/pglite/pglite.wasm +0 -0
- package/dist/setup-JWKZIECM.js +25 -0
- package/dist/signin-3M3UPB6K.js +667 -0
- package/dist/ssh-client-NWQVRCV7.js +29 -0
- package/dist/sso-oidc-3VDIYOEJ.js +834 -0
- package/dist/sts-B3WIYLXR.js +1426 -0
- package/dist/up-P5DMQ5YO.js +55 -0
- package/package.json +58 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
-- Durable failure classification for a deployment.
|
|
2
|
+
--
|
|
3
|
+
-- The pipeline already classifies failures precisely: a port conflict throws
|
|
4
|
+
-- DeployError(msg, "PORT_IN_USE", {port, pid, command, systemdUnit,
|
|
5
|
+
-- isManagedDeployment, …}) and that reaches onFailure intact. It was then split,
|
|
6
|
+
-- and only half of it was kept: `error_message` went to this table while
|
|
7
|
+
-- `errorCode`/`errorDetails` went ONLY to the in-memory SSE session. Once that
|
|
8
|
+
-- session was evicted (or the API restarted) all that survived a port conflict
|
|
9
|
+
-- was an English sentence, so nothing could offer the operator — or an MCP agent
|
|
10
|
+
-- — a way forward.
|
|
11
|
+
--
|
|
12
|
+
-- The one attempt to recover the code was inverted: build-status re-derived it
|
|
13
|
+
-- with error_message.includes("PORT_IN_USE"), and none of the coded messages
|
|
14
|
+
-- contain that token (they read "Port 3000 is already in use by …"). So the
|
|
15
|
+
-- failures we DID classify lost their code and the ones we didn't got it guessed.
|
|
16
|
+
--
|
|
17
|
+
-- `error_code` is free text with no check constraint, matching `status` on this
|
|
18
|
+
-- table: codes come from DeployError call sites across packages/adapters and must
|
|
19
|
+
-- be extendable without a migration. `error_details` is the DeployError details
|
|
20
|
+
-- bag verbatim (never contains secrets — it is process/port metadata).
|
|
21
|
+
--
|
|
22
|
+
-- Both nullable with no backfill: NULL means "not classified", which is exactly
|
|
23
|
+
-- true of every pre-existing row.
|
|
24
|
+
ALTER TABLE "deployment" ADD COLUMN IF NOT EXISTS "error_code" text;
|
|
25
|
+
--> statement-breakpoint
|
|
26
|
+
ALTER TABLE "deployment" ADD COLUMN IF NOT EXISTS "error_details" jsonb;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
-- Repair: create `project.readiness` on a database that skipped 0079.
|
|
2
|
+
--
|
|
3
|
+
-- WHY THIS EXISTS (and why it is not just "0079 again"):
|
|
4
|
+
--
|
|
5
|
+
-- 0079 was originally `0079_project_health_check` (adding `project.health_check`)
|
|
6
|
+
-- and was replaced in place by `0079_project_readiness` (adding
|
|
7
|
+
-- `project.readiness`) before either shipped. Both journal entries carry the SAME
|
|
8
|
+
-- `when` — 1785882107324 — because the second reused the first's slot.
|
|
9
|
+
--
|
|
10
|
+
-- drizzle's migrator reads only the single most recent applied row and applies a
|
|
11
|
+
-- migration when `lastDbMigration.created_at < migration.folderMillis`
|
|
12
|
+
-- (pg-core/dialect.js). That comparison is STRICT, so on any database that had
|
|
13
|
+
-- already run the old 0079, the new one is equal, not greater — it is skipped
|
|
14
|
+
-- without a word. 0080 carried a later stamp and applied normally, which is why
|
|
15
|
+
-- such a database ends up with 0080's columns, an orphan `health_check`, and no
|
|
16
|
+
-- `readiness` at all. Every query selecting the project row then dies with
|
|
17
|
+
-- `column "readiness" does not exist` (42703).
|
|
18
|
+
--
|
|
19
|
+
-- Bumping 0079's `when` would NOT fix it: the max applied stamp is now 0080's, so
|
|
20
|
+
-- anything ordered before 0080 still compares as already-applied. The repair has
|
|
21
|
+
-- to sort AFTER 0080, which is what this file is.
|
|
22
|
+
--
|
|
23
|
+
-- Idempotent on purpose. A fresh database creates the column at 0079 and this is
|
|
24
|
+
-- a no-op; a database that skipped 0079 creates it here. Either way the end state
|
|
25
|
+
-- is identical, so this is safe to leave in history permanently rather than being
|
|
26
|
+
-- a one-off someone has to remember to delete.
|
|
27
|
+
ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "readiness" jsonb;--> statement-breakpoint
|
|
28
|
+
|
|
29
|
+
-- Drop the column the replaced migration left behind. `health_check` was only
|
|
30
|
+
-- ever created by 0079_project_health_check, which never shipped in a release and
|
|
31
|
+
-- is referenced by no schema, query, or type in the codebase — so on the
|
|
32
|
+
-- databases that have it, it is dead weight with a confusingly similar name to
|
|
33
|
+
-- the compose service `healthcheck`. Guarded, so this is a no-op everywhere else.
|
|
34
|
+
ALTER TABLE "project" DROP COLUMN IF EXISTS "health_check";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
-- Proof that a routing TARGET is ours, as Kraft Cloud's shared edge now requires
|
|
2
|
+
-- before forwarding `<slug>.kraft.io` to it.
|
|
3
|
+
--
|
|
4
|
+
-- Keyed on (organization_id, target) because that is what the upstream keys it on:
|
|
5
|
+
-- one target serves every free domain on that box, so this is target-level state,
|
|
6
|
+
-- not domain-level. One install holds several rows — its own address plus one per
|
|
7
|
+
-- remote server it deploys to.
|
|
8
|
+
--
|
|
9
|
+
-- The token is persisted HERE, not only on the edge, because the upstream's list
|
|
10
|
+
-- endpoint returns id/target/status/expiry but NOT the token. Verification lasts 90
|
|
11
|
+
-- days and the upstream re-probes THE SAME token within 7 days of expiry; a 404 then
|
|
12
|
+
-- expires it and the free domain stops resolving ~83 days after a green deploy with
|
|
13
|
+
-- nothing in our logs. So a token that lived only on a box's disk would be
|
|
14
|
+
-- unrecoverable after a rebuild, and rows here are never deleted when a free domain
|
|
15
|
+
-- is dropped.
|
|
16
|
+
--
|
|
17
|
+
-- `server_id` is ON DELETE SET NULL, not cascade: losing the server row must not
|
|
18
|
+
-- take the token with it.
|
|
19
|
+
CREATE TABLE IF NOT EXISTS "edge_target_verification" (
|
|
20
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
21
|
+
"organization_id" text NOT NULL REFERENCES "organization"("id") ON DELETE CASCADE,
|
|
22
|
+
"target" text NOT NULL,
|
|
23
|
+
"host" text NOT NULL,
|
|
24
|
+
"server_id" text REFERENCES "servers"("id") ON DELETE SET NULL,
|
|
25
|
+
"verification_id" integer,
|
|
26
|
+
"token" text,
|
|
27
|
+
"retired_tokens" jsonb,
|
|
28
|
+
"challenge_path" text,
|
|
29
|
+
"status" text NOT NULL DEFAULT 'pending',
|
|
30
|
+
"validated_ip" text,
|
|
31
|
+
"expires_at" timestamp,
|
|
32
|
+
"last_checked_at" timestamp,
|
|
33
|
+
"last_error" text,
|
|
34
|
+
"created_at" timestamp NOT NULL DEFAULT now(),
|
|
35
|
+
"updated_at" timestamp NOT NULL DEFAULT now()
|
|
36
|
+
);
|
|
37
|
+
--> statement-breakpoint
|
|
38
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "uq_edge_target_verification"
|
|
39
|
+
ON "edge_target_verification" ("organization_id", "target");
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
-- Continuous container health monitoring: the durable memory behind the alerts.
|
|
2
|
+
--
|
|
3
|
+
-- Kraft knew a container had crashed at exactly ONE moment — the ~15s post-deploy
|
|
4
|
+
-- stabilization watch. After that nobody looked again, so an OOM-kill at 3am or a
|
|
5
|
+
-- Postgres that starts bouncing after a host reboot reached the operator only when a
|
|
6
|
+
-- user complained. The health watch closes that, but a poller that alerts on "the
|
|
7
|
+
-- container isn't running" gets muted within a day: a redeploy recreating containers,
|
|
8
|
+
-- an operator's `docker stop`, an unreachable host, and a crash loop all look exactly
|
|
9
|
+
-- like a failure at a point in time.
|
|
10
|
+
--
|
|
11
|
+
-- So the unit of alerting is an INCIDENT, not a state reading: opened once, escalated
|
|
12
|
+
-- only when it gets worse, resolved once with a downtime duration. This table is that
|
|
13
|
+
-- memory — it survives the control-plane restart that in-process state would not (a box
|
|
14
|
+
-- down for three days must not re-page on every API restart), and it doubles as the
|
|
15
|
+
-- project Health tab's history.
|
|
16
|
+
CREATE TABLE IF NOT EXISTS "service_incident" (
|
|
17
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
18
|
+
"organization_id" text NOT NULL REFERENCES "organization"("id") ON DELETE CASCADE,
|
|
19
|
+
-- Null for SERVER-scoped incidents (an unreachable box gets ONE incident, not one
|
|
20
|
+
-- per service on it — that fan-out is the single loudest source of alert fatigue).
|
|
21
|
+
"project_id" text REFERENCES "project"("id") ON DELETE CASCADE,
|
|
22
|
+
-- The resolved service row, when there is one. SET NULL, not cascade: deleting a
|
|
23
|
+
-- service must not erase the record of the outage it had (`service_key` still
|
|
24
|
+
-- identifies it, and `service_name` is snapshotted below).
|
|
25
|
+
"service_id" text REFERENCES "service"("id") ON DELETE SET NULL,
|
|
26
|
+
-- Stable identity across a container RECREATE, which is the whole point: every
|
|
27
|
+
-- deploy mints a new container id, so keying incidents on container id would open a
|
|
28
|
+
-- fresh incident for the same workload after each redeploy. Service id when we
|
|
29
|
+
-- resolved one, else the container name (single-app deploys have no service row);
|
|
30
|
+
-- `server:<id>` for server-scoped rows.
|
|
31
|
+
"service_key" text NOT NULL,
|
|
32
|
+
-- Snapshot of the display name at incident time — the alert text must still read
|
|
33
|
+
-- correctly after a rename, and history rows must not silently change meaning.
|
|
34
|
+
"service_name" text NOT NULL,
|
|
35
|
+
"server_id" text REFERENCES "servers"("id") ON DELETE SET NULL,
|
|
36
|
+
"container_id" text,
|
|
37
|
+
-- down | crash_loop | unhealthy | server_unreachable. Ordered by severity in the
|
|
38
|
+
-- watcher: an incident escalates upward (and re-notifies), never downward.
|
|
39
|
+
"kind" text NOT NULL,
|
|
40
|
+
"status" text NOT NULL DEFAULT 'open', -- open | resolved
|
|
41
|
+
"reason" text,
|
|
42
|
+
"exit_code" integer,
|
|
43
|
+
"restart_count" integer NOT NULL DEFAULT 0,
|
|
44
|
+
"oom_killed" boolean NOT NULL DEFAULT false,
|
|
45
|
+
-- Consecutive ticks that agreed on this verdict. An incident is only opened (and
|
|
46
|
+
-- only notified) at >= 2, so a snapshot taken mid-restart or during a slow
|
|
47
|
+
-- healthcheck start never pages anyone.
|
|
48
|
+
"confirmations" integer NOT NULL DEFAULT 0,
|
|
49
|
+
-- Notification bookkeeping. Deliberately a count, not a flag: open, escalation and
|
|
50
|
+
-- resolve each notify exactly once, and nothing else ever does.
|
|
51
|
+
"notify_count" integer NOT NULL DEFAULT 0,
|
|
52
|
+
"notified_at" timestamp,
|
|
53
|
+
"log_excerpt" text,
|
|
54
|
+
"opened_at" timestamp NOT NULL DEFAULT now(),
|
|
55
|
+
"resolved_at" timestamp,
|
|
56
|
+
-- Last tick that actually OBSERVED this workload. Not advanced when the host is
|
|
57
|
+
-- unreachable — during a connectivity loss we know nothing, so nothing is claimed.
|
|
58
|
+
"last_seen_at" timestamp NOT NULL DEFAULT now(),
|
|
59
|
+
"created_at" timestamp NOT NULL DEFAULT now(),
|
|
60
|
+
"updated_at" timestamp NOT NULL DEFAULT now()
|
|
61
|
+
);
|
|
62
|
+
--> statement-breakpoint
|
|
63
|
+
-- One open incident per workload — the dedup primitive. As a partial unique index,
|
|
64
|
+
-- "we are already alerting about this" is a DB invariant rather than sweep
|
|
65
|
+
-- bookkeeping: two overlapping ticks (a manual Run now landing on a cron tick) cannot
|
|
66
|
+
-- both open one and double-notify.
|
|
67
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "uq_service_incident_open"
|
|
68
|
+
ON "service_incident" ("project_id", "service_key")
|
|
69
|
+
WHERE "status" = 'open' AND "project_id" IS NOT NULL;
|
|
70
|
+
--> statement-breakpoint
|
|
71
|
+
-- Same invariant for server-scoped rows. Needs its own index because Postgres treats
|
|
72
|
+
-- NULLs as distinct in a unique index, so the one above would happily allow a second
|
|
73
|
+
-- open row for the same box.
|
|
74
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "uq_service_incident_open_server"
|
|
75
|
+
ON "service_incident" ("server_id")
|
|
76
|
+
WHERE "status" = 'open' AND "project_id" IS NULL;
|
|
77
|
+
--> statement-breakpoint
|
|
78
|
+
CREATE INDEX IF NOT EXISTS "idx_service_incident_project"
|
|
79
|
+
ON "service_incident" ("project_id", "opened_at" DESC);
|
|
80
|
+
--> statement-breakpoint
|
|
81
|
+
-- Intent marker. `disableProject` stopped the container and recorded NOTHING, so
|
|
82
|
+
-- "the operator turned this off" was unknowable — the health watch would page about
|
|
83
|
+
-- every deliberately-disabled project, forever. Set on disable, cleared on enable.
|
|
84
|
+
ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "disabled_at" timestamp;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
-- Widen the daily analytics rollup: distinct visitors, top paths, status mix.
|
|
2
|
+
--
|
|
3
|
+
-- The visitor pipeline already persisted per-country counts, and the dashboard
|
|
4
|
+
-- already rendered cards for "unique IPs" and a top-paths table. Neither was real:
|
|
5
|
+
-- `top_paths` was hardcoded `[]` in the service layer, and "unique IPs" was
|
|
6
|
+
-- `unique_requests` — the count of non-static REQUESTS — so five page views from
|
|
7
|
+
-- one browser read as five visitors. These columns are what makes those two
|
|
8
|
+
-- numbers mean what the UI has been claiming.
|
|
9
|
+
--
|
|
10
|
+
-- All three land HERE, on the daily table, rather than on the per-minute one:
|
|
11
|
+
-- visitors and paths are the high-cardinality metrics, and holding them per-minute
|
|
12
|
+
-- would multiply the edge's shared-dict key count by ~1440 to feed a chart nobody
|
|
13
|
+
-- asked for — evicting, in the process, the request counters they annotate.
|
|
14
|
+
-- Countries already live here for the same reason, and the edge keeps all four
|
|
15
|
+
-- under one `g:{domain}:{day}:` key prefix so a reader gets the whole day in a
|
|
16
|
+
-- single dict scan.
|
|
17
|
+
--
|
|
18
|
+
-- Additive with defaults on purpose: `migrations-additive.test.ts` rejects a
|
|
19
|
+
-- NOT NULL column without a DEFAULT, because an older cross-version dump omits the
|
|
20
|
+
-- column entirely and Drizzle then emits DEFAULT for it — with no default that's a
|
|
21
|
+
-- NULL into NOT NULL on the newer receiver, i.e. a broken cloud/project transfer.
|
|
22
|
+
|
|
23
|
+
-- Distinct visitors for the day, deduplicated AT THE EDGE and stored as a count.
|
|
24
|
+
--
|
|
25
|
+
-- Privacy is a property of where the dedup happens: the edge hashes each address
|
|
26
|
+
-- with a salt that is generated on that box, rotates daily, and never leaves its
|
|
27
|
+
-- shared memory. Only the cardinality of that set is written here. No address and
|
|
28
|
+
-- no per-visitor row exists at any layer, which is what keeps the published
|
|
29
|
+
-- "we don't collect behavioural analytics on your end users" true while still
|
|
30
|
+
-- reporting a real visitor number.
|
|
31
|
+
--
|
|
32
|
+
-- Understates on a very busy domain: the edge's `visitors` zone LRU-evicts past
|
|
33
|
+
-- roughly 1M distinct/day. mgmt_api `GET /status` reports that zone's free space so
|
|
34
|
+
-- a reader can label the number approximate instead of presenting an eviction
|
|
35
|
+
-- artifact as a measurement.
|
|
36
|
+
ALTER TABLE "server_analytics_geo" ADD COLUMN IF NOT EXISTS "visitors" integer DEFAULT 0 NOT NULL;
|
|
37
|
+
--> statement-breakpoint
|
|
38
|
+
|
|
39
|
+
-- Top paths: { "/": 900, "/orders/:id": 120, "other": 40 }.
|
|
40
|
+
--
|
|
41
|
+
-- Normalized at the edge before it ever becomes a key: query string stripped (so a
|
|
42
|
+
-- ?token= or ?session= can never be persisted here), numeric and UUID segments
|
|
43
|
+
-- collapsed to `:id`, key length capped, and the tail past a cardinality cap folded
|
|
44
|
+
-- into "other" — otherwise a scanner walking /wp-admin variants mints thousands of
|
|
45
|
+
-- permanent keys and evicts the real counters.
|
|
46
|
+
ALTER TABLE "server_analytics_geo" ADD COLUMN IF NOT EXISTS "paths" jsonb;
|
|
47
|
+
--> statement-breakpoint
|
|
48
|
+
|
|
49
|
+
-- Status-code mix: { "200": 4210, "404": 17, "502": 3 }. Status was captured into
|
|
50
|
+
-- the edge's raw-request ring buffer (RAM, 1h) but never aggregated, so error rate
|
|
51
|
+
-- was unanswerable from any persisted data. Bounded by construction.
|
|
52
|
+
ALTER TABLE "server_analytics_geo" ADD COLUMN IF NOT EXISTS "statuses" jsonb;
|
|
53
|
+
--> statement-breakpoint
|
|
54
|
+
|
|
55
|
+
-- Widen the per-minute bandwidth counters from int4 to int8.
|
|
56
|
+
--
|
|
57
|
+
-- These are bytes for ONE MINUTE, and int4 caps at 2,147,483,647 — about 2.1 GB,
|
|
58
|
+
-- which a single minute reaches at roughly 286 Mbps. That is unremarkable for a
|
|
59
|
+
-- site serving video or large downloads. Past it Postgres raises "integer out of
|
|
60
|
+
-- range", the upsert for that minute fails, and the scrape for the whole domain
|
|
61
|
+
-- dies with it — so the busiest domains on a box would be precisely the ones with
|
|
62
|
+
-- no analytics, and it would look like the feature simply didn't work for them.
|
|
63
|
+
--
|
|
64
|
+
-- Now that collection runs unattended on a schedule rather than only when someone
|
|
65
|
+
-- opens the tab, that failure would happen in a job with nobody reading the error.
|
|
66
|
+
--
|
|
67
|
+
-- Widening is lossless and there is no application change: the edge already
|
|
68
|
+
-- accumulates these as Lua numbers (doubles, exact to 2^53) and Drizzle reads them
|
|
69
|
+
-- back with mode:"number", which is exact over the same range.
|
|
70
|
+
ALTER TABLE "server_analytics" ALTER COLUMN "bandwidth_in" TYPE bigint;
|
|
71
|
+
--> statement-breakpoint
|
|
72
|
+
ALTER TABLE "server_analytics" ALTER COLUMN "bandwidth_out" TYPE bigint;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
-- Resource usage history: the persisted series behind the Monitoring tab's
|
|
2
|
+
-- CPU/memory chart.
|
|
3
|
+
--
|
|
4
|
+
-- Usage existed only as a live 5-second SSE stream, so closing the tab discarded
|
|
5
|
+
-- everything. "Was memory climbing before the OOM at 3am" was unanswerable, which is
|
|
6
|
+
-- the question the data exists to answer.
|
|
7
|
+
--
|
|
8
|
+
-- ── Why this is a SAMPLED series, not a counter series like server_analytics ──
|
|
9
|
+
--
|
|
10
|
+
-- Traffic is counted for free: the edge increments a shared-dict key on every
|
|
11
|
+
-- request, so per-minute granularity costs nothing and is exact. Resource usage has
|
|
12
|
+
-- to be PROBED, and `docker stats` occupies the daemon for roughly a second per
|
|
13
|
+
-- container because it must collect two CPU samples to compute a delta — about 500x
|
|
14
|
+
-- a `docker inspect`. The sampling cadence therefore IS the resolution, and the cost
|
|
15
|
+
-- scales with container count. 5-minute buckets are the compromise between catching
|
|
16
|
+
-- a spike and not pinning every daemon on the estate; ~288 rows/day/service.
|
|
17
|
+
--
|
|
18
|
+
-- ── serviceKey is NOT NULL text, not a nullable service_id FK ────────────────
|
|
19
|
+
--
|
|
20
|
+
-- Postgres treats NULLs as DISTINCT in a unique index, so a nullable column cannot
|
|
21
|
+
-- carry the "this row is the project itself" case without the partial-index
|
|
22
|
+
-- workaround migration 0083 needed for service_incident. A sentinel ('__app__',
|
|
23
|
+
-- matching the health watch's own constant so both features name the same workload
|
|
24
|
+
-- identically) keeps one plain unique index correct.
|
|
25
|
+
--
|
|
26
|
+
-- Accepted consequence: deleting a service leaves its samples behind until retention
|
|
27
|
+
-- prunes them. That is the right trade — history should outlive the thing it
|
|
28
|
+
-- describes — and the project cascade still bounds the growth.
|
|
29
|
+
--
|
|
30
|
+
-- ── What is deliberately absent ─────────────────────────────────────────────
|
|
31
|
+
--
|
|
32
|
+
-- No project-total row. For a compose project the total is the per-bucket SUM of its
|
|
33
|
+
-- services, computed at read. Storing it too would duplicate rows that are free to
|
|
34
|
+
-- drift from their own sources, and would be wrong the moment a service is added or
|
|
35
|
+
-- removed mid-window.
|
|
36
|
+
CREATE TABLE IF NOT EXISTS "resource_usage" (
|
|
37
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
38
|
+
"project_id" text NOT NULL REFERENCES "project"("id") ON DELETE CASCADE,
|
|
39
|
+
-- service.id, or '__app__' for a single-container project.
|
|
40
|
+
"service_key" text NOT NULL,
|
|
41
|
+
-- Bucket start in epoch MINUTES (not a timestamp), floored to a multiple of 5 —
|
|
42
|
+
-- same integer-bucket convention as server_analytics.
|
|
43
|
+
"minute" integer NOT NULL,
|
|
44
|
+
-- Per-CORE percent, as the runtimes report it: >100 is correct on a multi-core box
|
|
45
|
+
-- and must not be clamped. Readers divide by core count for "share of this host".
|
|
46
|
+
"cpu_percent" real DEFAULT 0 NOT NULL,
|
|
47
|
+
"memory_mb" real DEFAULT 0 NOT NULL,
|
|
48
|
+
-- CUMULATIVE since container start, not per-bucket deltas — that is what the
|
|
49
|
+
-- runtimes expose. Readers difference consecutive buckets and clamp negatives to
|
|
50
|
+
-- zero, because a restart resets the counter and would otherwise plot as a large
|
|
51
|
+
-- negative spike. bigint: a long-lived busy container passes int4 in days.
|
|
52
|
+
-- Always 0 for bare deploys (per-process accounting needs eBPF or a netns), so a
|
|
53
|
+
-- reader must not present 0 here as "no network traffic".
|
|
54
|
+
"network_rx_bytes" bigint DEFAULT 0 NOT NULL,
|
|
55
|
+
"network_tx_bytes" bigint DEFAULT 0 NOT NULL,
|
|
56
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
57
|
+
);
|
|
58
|
+
--> statement-breakpoint
|
|
59
|
+
|
|
60
|
+
-- Makes a repeated sample for the same bucket a no-op (insert ... on conflict do
|
|
61
|
+
-- nothing) rather than a double count, so the whole sweep is safely re-runnable.
|
|
62
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "uq_resource_usage_project_service_minute"
|
|
63
|
+
ON "resource_usage" ("project_id", "service_key", "minute");
|
|
64
|
+
--> statement-breakpoint
|
|
65
|
+
|
|
66
|
+
-- Every read is "this project over this window".
|
|
67
|
+
CREATE INDEX IF NOT EXISTS "idx_resource_usage_project_minute"
|
|
68
|
+
ON "resource_usage" ("project_id", "minute");
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
-- Remote infra (edge / mail container) update tracking.
|
|
2
|
+
--
|
|
3
|
+
-- When the control plane's APP_VERSION moves forward, the edge/mail containers
|
|
4
|
+
-- already deployed on remote servers stay on their old image tag. Two additions
|
|
5
|
+
-- drive the "monitor → advise → apply" loop for that drift:
|
|
6
|
+
--
|
|
7
|
+
-- instance_settings.auto_update_infra / last_seen_version — the instance-wide
|
|
8
|
+
-- auto-update toggle and the version the infra reconcile last ran for (so the
|
|
9
|
+
-- boot hook fires exactly once per upgrade). Both additive: the boolean
|
|
10
|
+
-- carries a DEFAULT, last_seen_version is nullable.
|
|
11
|
+
--
|
|
12
|
+
-- server_container_status — the container sibling of server_module_status.
|
|
13
|
+
-- One row per (server, component); "behind" is a plain tag comparison
|
|
14
|
+
-- (running image ref != pinned image ref), since infra images are pinned to
|
|
15
|
+
-- APP_VERSION. Mirrors the module table's org+behind index and unique key.
|
|
16
|
+
ALTER TABLE "instance_settings" ADD COLUMN IF NOT EXISTS "auto_update_infra" boolean DEFAULT false NOT NULL;
|
|
17
|
+
--> statement-breakpoint
|
|
18
|
+
ALTER TABLE "instance_settings" ADD COLUMN IF NOT EXISTS "last_seen_version" text;
|
|
19
|
+
--> statement-breakpoint
|
|
20
|
+
CREATE TABLE IF NOT EXISTS "server_container_status" (
|
|
21
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
22
|
+
"organization_id" text REFERENCES "organization"("id") ON DELETE CASCADE,
|
|
23
|
+
"server_id" text NOT NULL REFERENCES "servers"("id") ON DELETE CASCADE,
|
|
24
|
+
"component" text NOT NULL,
|
|
25
|
+
"running_label" text,
|
|
26
|
+
"pinned_label" text,
|
|
27
|
+
"running_version" text,
|
|
28
|
+
"pinned_version" text,
|
|
29
|
+
"behind" boolean DEFAULT false NOT NULL,
|
|
30
|
+
"latest_in_progress" boolean DEFAULT false NOT NULL,
|
|
31
|
+
"detail" jsonb,
|
|
32
|
+
"checked_at" timestamp DEFAULT now() NOT NULL,
|
|
33
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
34
|
+
"updated_at" timestamp DEFAULT now() NOT NULL
|
|
35
|
+
);
|
|
36
|
+
--> statement-breakpoint
|
|
37
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "uq_server_container_status"
|
|
38
|
+
ON "server_container_status" ("server_id", "component");
|
|
39
|
+
--> statement-breakpoint
|
|
40
|
+
CREATE INDEX IF NOT EXISTS "idx_server_container_status_org_behind"
|
|
41
|
+
ON "server_container_status" ("organization_id", "behind");
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
-- Repair: add `server_container_status.running_version` / `pinned_version` on a
|
|
2
|
+
-- database that ran an earlier form of 0086.
|
|
3
|
+
--
|
|
4
|
+
-- 0086 was edited in place after it had already been applied: the version columns
|
|
5
|
+
-- were added to its CREATE TABLE, but that create is `IF NOT EXISTS`, so on any
|
|
6
|
+
-- database that had already run the older 0086 the table exists and the amended
|
|
7
|
+
-- create is a silent no-op — the columns never appear. drizzle's migrator then
|
|
8
|
+
-- refuses to re-run 0086 (its `when` equals the last-applied stamp, and the
|
|
9
|
+
-- comparison is strict `<`; see 0081_project_readiness_repair for the same trap),
|
|
10
|
+
-- so nothing else patches it either. Every `listByOrg` then dies with
|
|
11
|
+
-- `column "running_version" does not exist` (42703).
|
|
12
|
+
--
|
|
13
|
+
-- Idempotent and stamped after 0086, so it sorts as a fresh migration: a database
|
|
14
|
+
-- created cleanly gets the columns at 0086 and this is a no-op; a database that
|
|
15
|
+
-- ran the stale 0086 gets them here. Safe to keep in history permanently.
|
|
16
|
+
ALTER TABLE "server_container_status" ADD COLUMN IF NOT EXISTS "running_version" text;--> statement-breakpoint
|
|
17
|
+
ALTER TABLE "server_container_status" ADD COLUMN IF NOT EXISTS "pinned_version" text;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
-- Audit log: call source + per-org recording switch.
|
|
2
|
+
--
|
|
3
|
+
-- audit_event.source — WHERE the action came in from: "dashboard", "mcp",
|
|
4
|
+
-- "cli", "api", "webhook", "system". Nullable on purpose: rows written
|
|
5
|
+
-- before this migration have no knowable source and must not be
|
|
6
|
+
-- mislabelled as any particular one, so they render as "Unknown". This is
|
|
7
|
+
-- what makes "show me only what the AI assistant did" answerable at all —
|
|
8
|
+
-- MCP tool calls re-enter the app through app.fetch() with nothing but an
|
|
9
|
+
-- Authorization header, so until now an MCP-driven write and a CLI write
|
|
10
|
+
-- produced identical rows.
|
|
11
|
+
--
|
|
12
|
+
-- audit_settings — recording on/off + retention, PER ORGANIZATION. Not
|
|
13
|
+
-- instance_settings (one row would let a single tenant disable auditing for
|
|
14
|
+
-- every org on a CLOUD_MODE instance) and not organization.metadata (Better
|
|
15
|
+
-- Auth owns those writes, which is why the auditRetentionDays documented
|
|
16
|
+
-- there never got a writer). Default enabled = true: auditing stays on
|
|
17
|
+
-- unless an admin turns it off.
|
|
18
|
+
ALTER TABLE "audit_event" ADD COLUMN IF NOT EXISTS "source" text;
|
|
19
|
+
--> statement-breakpoint
|
|
20
|
+
CREATE INDEX IF NOT EXISTS "audit_event_org_source_idx" ON "audit_event" ("organization_id","source","created_at" DESC);
|
|
21
|
+
--> statement-breakpoint
|
|
22
|
+
CREATE TABLE IF NOT EXISTS "audit_settings" (
|
|
23
|
+
"organization_id" text PRIMARY KEY NOT NULL REFERENCES "organization"("id") ON DELETE CASCADE,
|
|
24
|
+
"enabled" boolean DEFAULT true NOT NULL,
|
|
25
|
+
"retention_days" integer DEFAULT 90 NOT NULL,
|
|
26
|
+
"updated_at" timestamp DEFAULT now() NOT NULL
|
|
27
|
+
);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
-- instance_settings.auto_scan_infra — when on (default), the dashboard runs one
|
|
2
|
+
-- detect-only container scan on a relevant surface load (Infrastructure tab /
|
|
3
|
+
-- home) if the cached drift state is stale, so the attention dot + issue list
|
|
4
|
+
-- stay fresh without a manual Scan. Detect-only; auto-APPLY stays the separate
|
|
5
|
+
-- auto_update_infra. Idempotent ADD COLUMN IF NOT EXISTS + DEFAULT true so both
|
|
6
|
+
-- a clean create and an existing settings row converge on "on".
|
|
7
|
+
ALTER TABLE "instance_settings" ADD COLUMN IF NOT EXISTS "auto_scan_infra" boolean DEFAULT true NOT NULL;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
-- Top Paths becomes opt-in.
|
|
2
|
+
--
|
|
3
|
+
-- The per-path aggregation is the one analytics dimension that isn't effectively free.
|
|
4
|
+
-- Measured on the shipped edge image, per request:
|
|
5
|
+
--
|
|
6
|
+
-- paths (whole block) 1.72 us <- 57% of the log handler's counter path
|
|
7
|
+
-- of which string work 1.38 us normalize_path + is_static_asset
|
|
8
|
+
-- minute buckets 0.61 us
|
|
9
|
+
-- country 0.24 us
|
|
10
|
+
-- status 0.14 us
|
|
11
|
+
--
|
|
12
|
+
-- It is also the highest-cardinality dimension (up to 2000 keys per domain per day) and
|
|
13
|
+
-- the largest column in the daily rollup. So it is now a per-project switch, read on the
|
|
14
|
+
-- hot path from the edge's `rules` shared dict and pushed there on every route apply.
|
|
15
|
+
--
|
|
16
|
+
-- DEFAULT false, which turns it off for existing projects as well. Deliberate: no one
|
|
17
|
+
-- opted into the cost, so no one should keep paying it without asking.
|
|
18
|
+
ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "collect_paths" boolean DEFAULT false NOT NULL;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
-- Durable server ownership on the project.
|
|
2
|
+
--
|
|
3
|
+
-- A project's deploy target lived ONLY in the active deployment's volatile
|
|
4
|
+
-- meta.serverId. When resolveSnapshotTarget couldn't re-derive that binding from
|
|
5
|
+
-- a fresh/partial snapshot, the deploy fell back to "local", which then nulled
|
|
6
|
+
-- the project's verified custom-domain ports and regressed the Access URL to
|
|
7
|
+
-- localhost:3000. This makes the server binding a durable, first-class column.
|
|
8
|
+
--
|
|
9
|
+
-- cloudWorkspaceId still owns "is this a cloud project", so we deliberately do
|
|
10
|
+
-- NOT add a deployTarget column (that would be a second source of truth for the
|
|
11
|
+
-- same fact); the effective target is derived — cloudWorkspaceId ? "cloud" :
|
|
12
|
+
-- server_id ? "server" : "local".
|
|
13
|
+
--
|
|
14
|
+
-- ON DELETE SET NULL: removing a server unbinds its projects rather than
|
|
15
|
+
-- cascade-deleting them.
|
|
16
|
+
ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "server_id" text REFERENCES "servers"("id") ON DELETE SET NULL;
|
|
17
|
+
--> statement-breakpoint
|
|
18
|
+
-- Backfill the binding from each project's active-deployment meta so existing
|
|
19
|
+
-- server-hosted projects survive the next redeploy without regressing to local.
|
|
20
|
+
UPDATE "project" SET "server_id" = (
|
|
21
|
+
SELECT d."meta"->>'serverId'
|
|
22
|
+
FROM "deployment" d
|
|
23
|
+
WHERE d."id" = "project"."active_deployment_id"
|
|
24
|
+
)
|
|
25
|
+
WHERE "server_id" IS NULL
|
|
26
|
+
AND "active_deployment_id" IS NOT NULL;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
-- User-chosen internal DNS alias for a single-app native project.
|
|
2
|
+
--
|
|
3
|
+
-- Single-app containers now join their own `kraft-<slug>` network with a
|
|
4
|
+
-- stable default alias (`<slug>`), the same east-west reachability compose
|
|
5
|
+
-- services already have. This column lets an operator add a custom hostname
|
|
6
|
+
-- that resolves ALONGSIDE the default (both point at the container) — it never
|
|
7
|
+
-- replaces the default and never changes public exposure (the edge stays the
|
|
8
|
+
-- sole public ingress; publishing is loopback-only).
|
|
9
|
+
--
|
|
10
|
+
-- Nullable, no default: absence means "default alias only" and existing rows
|
|
11
|
+
-- need no backfill. Compose services store the equivalent in the zero-migration
|
|
12
|
+
-- `service.advanced.alias` JSONB, so only single-app needs a column.
|
|
13
|
+
ALTER TABLE "project" ADD COLUMN IF NOT EXISTS "internal_alias" text;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
-- Org-wide incident reads for the global issue tracker.
|
|
2
|
+
--
|
|
3
|
+
-- The existing indexes on this table are project-keyed (`idx_service_incident_project`)
|
|
4
|
+
-- or exist to enforce the one-open-incident invariant. Both are wrong shapes for the
|
|
5
|
+
-- new question: "every incident in THIS organization, newest first" — the Issues feed's
|
|
6
|
+
-- Open tab and its Resolved tab, which sorts org-wide across up to 30 days of retained
|
|
7
|
+
-- history. Without this the feed sequentially scans the whole table and filters, which
|
|
8
|
+
-- gets slower exactly as an instance accumulates the history that makes the tab useful.
|
|
9
|
+
--
|
|
10
|
+
-- Covers both scopes: server-scoped rows have `project_id IS NULL`, so a project-keyed
|
|
11
|
+
-- index can't serve them at all.
|
|
12
|
+
CREATE INDEX IF NOT EXISTS "idx_service_incident_org"
|
|
13
|
+
ON "service_incident" ("organization_id", "opened_at" DESC);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
-- Record WHICH integrity check a restore actually performed.
|
|
2
|
+
--
|
|
3
|
+
-- Prepare used to comment that it verified every artifact's sha256 while
|
|
4
|
+
-- comparing only byte sizes. Now that it really re-hashes the archive, the row
|
|
5
|
+
-- has to say so — because the check is downgradeable (a run with no recorded
|
|
6
|
+
-- digest falls back to size-only, and a policy can defer verification to apply
|
|
7
|
+
-- time), and "restore succeeded" means something different in each case. An
|
|
8
|
+
-- operator reading a month-old restore has no other way to tell a re-hashed
|
|
9
|
+
-- archive from a length-matched one.
|
|
10
|
+
--
|
|
11
|
+
-- Keys written today: `integrity` ("sha256" | "size-only" | "deferred"),
|
|
12
|
+
-- `verifiedBytes`, `verifyMs`, `manifest` ("verified" | "missing").
|
|
13
|
+
-- JSONB rather than columns so the cancel/partial-write facts that follow need
|
|
14
|
+
-- no further migration.
|
|
15
|
+
ALTER TABLE "backup_restore" ADD COLUMN IF NOT EXISTS "meta" jsonb DEFAULT '{}'::jsonb;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
-- Make "cancel a restore" durable.
|
|
2
|
+
--
|
|
3
|
+
-- Cancel used to be advisory at best: it refused `applying` outright, and for
|
|
4
|
+
-- `preparing` it wrote the row while the running phase carried on and
|
|
5
|
+
-- overwrote it with `prepared` — so the operator saw a cancel that never
|
|
6
|
+
-- happened. Cancelling has to survive the phase it interrupts, and the node
|
|
7
|
+
-- receiving the request is not guaranteed to be the node running the apply, so
|
|
8
|
+
-- the in-process AbortController cannot be the only signal.
|
|
9
|
+
--
|
|
10
|
+
-- `cancel_requested_at` is also the force-terminal window: an `applying` row
|
|
11
|
+
-- whose request is older than a couple of minutes (operator pressed cancel,
|
|
12
|
+
-- waited, pressed again) can be force-terminaled without a second endpoint,
|
|
13
|
+
-- which is the only escape from a wedged row that otherwise blocks project
|
|
14
|
+
-- deletion.
|
|
15
|
+
ALTER TABLE "backup_restore" ADD COLUMN IF NOT EXISTS "cancel_requested" boolean DEFAULT false NOT NULL;
|
|
16
|
+
--> statement-breakpoint
|
|
17
|
+
ALTER TABLE "backup_restore" ADD COLUMN IF NOT EXISTS "cancel_requested_at" timestamp;
|
|
18
|
+
--> statement-breakpoint
|
|
19
|
+
ALTER TABLE "backup_restore" ADD COLUMN IF NOT EXISTS "cancelled_at" timestamp;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- Turn retention on for policies that never said anything about it.
|
|
2
|
+
--
|
|
3
|
+
-- `retain_count` and `retain_days` were the only two fields on the policy
|
|
4
|
+
-- insert with neither an API default nor a column default, so every policy
|
|
5
|
+
-- created through the API or MCP stored NULL for both. `prunePolicy`
|
|
6
|
+
-- short-circuits on "no retention configured", so retention silently never ran
|
|
7
|
+
-- for those policies and their runs accumulated until the destination filled.
|
|
8
|
+
-- The dashboard's form defaults to 7, so a human creating a policy in the UI
|
|
9
|
+
-- got retention and the same policy created over the API did not.
|
|
10
|
+
--
|
|
11
|
+
-- 7 = the dashboard's own default (PolicyEditor), now shared as
|
|
12
|
+
-- DEFAULT_RETAIN_COUNT so the column, the API fallback, and the form agree.
|
|
13
|
+
--
|
|
14
|
+
-- The backfill is what actually fixes instances running today, and it is
|
|
15
|
+
-- narrowed to rows where BOTH fields are null: a policy with only `retain_days`
|
|
16
|
+
-- set has retention configured deliberately, and writing a count there would
|
|
17
|
+
-- silently tighten a window the operator chose.
|
|
18
|
+
ALTER TABLE "backup_policy" ALTER COLUMN "retain_count" SET DEFAULT 7;
|
|
19
|
+
--> statement-breakpoint
|
|
20
|
+
UPDATE "backup_policy" SET "retain_count" = 7 WHERE "retain_count" IS NULL AND "retain_days" IS NULL;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
-- update_status becomes an UPSTREAM-only cache.
|
|
2
|
+
--
|
|
3
|
+
-- The table used to cache both halves of the drift answer: what the source offers
|
|
4
|
+
-- (upstream) and what is currently deployed. Only the first half is expensive and
|
|
5
|
+
-- poll-only. The second half — `behind`, `latest_in_progress`, `current_label` —
|
|
6
|
+
-- is derived from the project's ACTIVE deployment, which seven separate code paths
|
|
7
|
+
-- write (deploy success, rollback, reconcile, activate, clear, self-deploy,
|
|
8
|
+
-- migrate). Caching it meant each of those needed an invalidation hook; only one
|
|
9
|
+
-- ever had it, so rows froze mid-window and the dashboard advertised updates for
|
|
10
|
+
-- commits the operator had already shipped.
|
|
11
|
+
--
|
|
12
|
+
-- Those columns are now computed on read, so keeping them would leave a copy that
|
|
13
|
+
-- looks authoritative while describing a superseded release. `latest_label` goes
|
|
14
|
+
-- too: it's rendered from `detail` alongside the live current label, in one code
|
|
15
|
+
-- path, so the two can never disagree.
|
|
16
|
+
--
|
|
17
|
+
-- Existing rows keep `detail`, but rows written before this migration carry only
|
|
18
|
+
-- the 7-char sha prefix in the dropped `latest_label` — never a full `latestSha`
|
|
19
|
+
-- in `detail` — so a commit row cannot be compared until it is re-polled. Clear
|
|
20
|
+
-- them and let `updates:scan` (or the dashboard's explicit check) repopulate;
|
|
21
|
+
-- until then those projects simply report no update, which is the conservative
|
|
22
|
+
-- direction.
|
|
23
|
+
DELETE FROM "update_status";
|
|
24
|
+
--> statement-breakpoint
|
|
25
|
+
DROP INDEX IF EXISTS "idx_update_status_org_behind";
|
|
26
|
+
--> statement-breakpoint
|
|
27
|
+
CREATE INDEX IF NOT EXISTS "idx_update_status_org" ON "update_status" ("organization_id");
|
|
28
|
+
--> statement-breakpoint
|
|
29
|
+
ALTER TABLE "update_status" DROP COLUMN IF EXISTS "behind";
|
|
30
|
+
--> statement-breakpoint
|
|
31
|
+
ALTER TABLE "update_status" DROP COLUMN IF EXISTS "latest_in_progress";
|
|
32
|
+
--> statement-breakpoint
|
|
33
|
+
ALTER TABLE "update_status" DROP COLUMN IF EXISTS "current_label";
|
|
34
|
+
--> statement-breakpoint
|
|
35
|
+
ALTER TABLE "update_status" DROP COLUMN IF EXISTS "latest_label";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- Kraft Mail: which product this instance presents itself as.
|
|
2
|
+
--
|
|
3
|
+
-- Nullable with NO default, deliberately. The instance_settings row exists on
|
|
4
|
+
-- every instance, so a NOT NULL DEFAULT 'platform' would write a concrete value
|
|
5
|
+
-- everywhere and permanently shadow the KRAFT_PRODUCT env var — the resolver
|
|
6
|
+
-- reads `settings.product_mode ?? env.KRAFT_PRODUCT`, so "unset" has to stay
|
|
7
|
+
-- representable. NULL means "no instance override".
|
|
8
|
+
--
|
|
9
|
+
-- Presentation scope only: this hides nav entries and rebrands the shell. It is
|
|
10
|
+
-- not an authorization boundary and no route reads it — webmail deploys through
|
|
11
|
+
-- the ordinary project pipeline, so the platform endpoints stay live in mail mode.
|
|
12
|
+
ALTER TABLE "instance_settings" ADD COLUMN IF NOT EXISTS "product_mode" text;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
-- The webmail project serving a mail server, as a stored FK.
|
|
2
|
+
--
|
|
3
|
+
-- Webmail is now an ordinary catalog app (packages/core/src/apps/catalog/webmail.json)
|
|
4
|
+
-- installed through the SAME generic installer as every other app, so its slug is
|
|
5
|
+
-- derived from the project NAME the operator typed. The link therefore cannot be a
|
|
6
|
+
-- naming convention any more: the old lookup parsed `webmail-<serverId>` back out of
|
|
7
|
+
-- the slug, which the generic installer never produces — and which, while it existed,
|
|
8
|
+
-- mislinked any project a user happened to name "Webmail Prod" (slug `webmail-prod`,
|
|
9
|
+
-- read back as mail server "prod").
|
|
10
|
+
--
|
|
11
|
+
-- Nullable: most servers have no webmail, and an operator may run one outside
|
|
12
|
+
-- kraft. ON DELETE SET NULL so deleting the webmail project clears the link and
|
|
13
|
+
-- /emails falls back to the install CTA rather than pointing at a row that is gone.
|
|
14
|
+
--
|
|
15
|
+
-- No backfill. A pre-existing webmail project still carries the retired
|
|
16
|
+
-- `mail-webmail` template id and the `webmail-<serverId>` slug; the mail status
|
|
17
|
+
-- resolver keeps that legacy slug lookup as a fallback for exactly those rows, and
|
|
18
|
+
-- stamps this column the first time it resolves one.
|
|
19
|
+
ALTER TABLE "mail_servers" ADD COLUMN IF NOT EXISTS "webmail_project_id" text;--> statement-breakpoint
|
|
20
|
+
|
|
21
|
+
DO $$ BEGIN
|
|
22
|
+
ALTER TABLE "mail_servers" ADD CONSTRAINT "mail_servers_webmail_project_id_project_id_fk"
|
|
23
|
+
FOREIGN KEY ("webmail_project_id") REFERENCES "public"."project"("id") ON DELETE set null ON UPDATE no action;
|
|
24
|
+
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
|