ProjectSend Cloud already appears in LICENSING.md and CONTRIBUTING.md,
but not in the README — the first thing people and search engines read.
One paragraph after the intro names it, says who runs it, and points to
LICENSING.md for where the line between the free core and Cloud sits.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Three lines still told readers S3 was the only option, which stopped
being true and is the sort of thing somebody chooses a different product
over. The install guide's storage section now says what each backend is
for, that Test connection exists and is worth using before switching
uploads over, and — the part people actually get wrong — that choosing a
backend applies to new uploads and moves nothing that is already stored.
The example compose file shipped with ADMIN_NAME/ADMIN_EMAIL/ADMIN_PASSWORD
filled in, so the entrypoint created the first administrator and nobody ever
reached the setup screen the README, the Docker Hub page and the website all
promise. Someone who followed the instructions literally — edit APP_URL and
the passwords — also ended up with a publicly reachable administrator on
admin@example.com with a password printed in a public file.
Comment the three variables out. Unattended provisioning still works for
anyone who wants it, it is just opt-in now, and the first thing a new install
shows is the setup screen again.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The README told everybody to clone the repository and run the development
stack, which builds nothing and installs nothing — so a user following it
got a crash-looping worker and a 500, and reported it as a bug (#1627).
They were reading the right document; it was pointing at the wrong stack.
Getting started now says what each path is for. Users fetch
compose.example.yaml and run the published image, which ships vendored and
pre-built and needs no toolchain — it has existed all along and was linked
from nowhere in the README. Contributors get one paragraph saying a clone
is a development copy, not an installation, and a pointer to
CONTRIBUTING.md, whose sequence was already correct.
CONTRIBUTING gains the sentence its readers were missing — why those steps
exist at all — plus the two things a contributor now meets: containers
that name the missing step instead of dying silently, and the fact that a
second checkout shares one Compose project name and will take over the
first one's containers. That last one cost me this working copy's stack
for a few minutes.
Also: DOCKER.md and INSTALL.md both linked README.md#development, an
anchor that has never existed. And UPDATE.md's build-from-source path told
operators to pull and rebuild with no dependency step, which is the same
trap on every release that moves composer.lock.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Updating had a numbered list inside INSTALL.md and a code block in the
dashboard, and between them they were missing the step that decides
whether an update works at all.
Rehearsed both paths end to end against a real 2.0.0 install before
writing any of this down. On Docker the whole update is `docker compose
pull && docker compose up -d`: the entrypoint waits for the database,
migrates, ensures the roles, and starts the workers, and it does not
start nginx until that finishes — so a failed migration is a container
that stays down rather than a half-updated site taking traffic. The
generated APP_KEY on the storage volume is left alone. Verified: 69
migrations to 73, key unchanged, data intact, healthcheck healthy.
The manual path is where the gap was. Replace the files, run the four
documented commands, and the site still serves the old version: with
`opcache.validate_timestamps=0` — what every production guide recommends,
and what our own image ships — PHP never re-reads a file it has already
compiled. The database is on the new version, every visitor is on the
old code, and `php artisan` cheerfully reports the new version the whole
time you are trying to work out why. Reproduced exactly that, then
watched a php-fpm reload fix it.
UPDATE.md is now the whole procedure for both, INSTALL.md keeps the short
sequence with the reload added, and the in-app instructions gained the
same line — in the code block, which is not translated, so no locale is
left saying something different.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
The retake was 2720x2664 — near square, because it fitted both columns
of widgets end to end. Next to files.png and portal.png, both 16:10, it
read as a different kind of picture and took three times the vertical
room in the README for it.
Same 1360x850 at 2x the other two use. The point was never that every
widget be legible in one frame — only that they all be switched on, so
the installation looks like one somebody uses rather than one nobody has
configured.
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
The old one photographed a development database: 58 files totalling
7.3 MB, "template-business" and "new-editor" among the largest, two
clients in the storage table, and eight identical "Logged in" rows as
the recent activity. It showed the layout and none of the point.
This one is a plausible installation — real-sounding client
organisations against their quotas, files with names and sizes somebody
would recognise, a month of uploads and downloads with a working week's
rhythm in it, and activity that says what people did rather than that
they arrived. Every widget is on, in the two-column layout, so the
picture also answers "what does this thing actually track".
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Client file sharing, rebuilt from the ground up: a private area per
client, resumable uploads, folders, groups and categories, sharing with
expiry dates and download limits, comments, file versions, an activity
log, a REST API, and sixteen languages.
This repository begins here. ProjectSend 2 was developed privately, and
that development history is not published — the previous generation
remains available, with its own history, at projectsend/legacy.
Free software under the GNU General Public License v2, or (at your
option) any later version.