app.R and the supplied
projects.rds together.install.packages(c("shiny", "DT", "digest", "filelock", "googledrive"))
shiny::runApp()
The default is local mode. It reads the original projects.rds and
creates data/lef-projects-v2.rds on the first successful
save. The original file is never overwritten. Subsequent launches use
the version 2 file.
Enter your name in the sidebar before saving. This is an attribution field, not an authenticated identity. Use your hosting platform’s access controls for a private lab deployment.
Project names and original stage dates are preserved. People are not guessed from underscore-separated titles. Lead, supervisor, and collaborators are blank until reviewed. Creation and last-update dates remain unknown until appropriate; legacy projects are therefore initially flagged for a check-in, not as overdue.
The old stage codes look like completed milestones. The initial mapping is:
| Original value | New current activity | Status |
|---|---|---|
| initiated | Planning | Active |
| data_collected | Laboratory analyses | Active |
| lab_analyses_done | Data analysis | Active |
| data_processing_done | Writing | Active |
| paper_submitted | Submitted / revision | Active |
| paper_published | Published | Completed |
| project_terminated | Planning (placeholder) | Discontinued, archived |
Review these mappings for each project: old UI labels were ambiguous.
Projects without laboratory work can move directly to data analysis; old
analysis/writing projects may already be further ahead. The original
code is retained in legacy_stage, visible in Details. The
original date is retained in stage_changed. A discontinued
project’s earlier scientific stage is unknown.
Stage, health, status, and archive are independent. For example, an on-hold project can remain in Writing. Moving to Published does not automatically change status; set Completed when appropriate. There is no permanent-delete UI.
This retains the original Drive workflow but uses an exact filename and updates an existing file instead of deleting and re-uploading it.
Set environment variables before launching the app (or in a private
.Renviron):
LEF_STORAGE=drive
LEF_DRIVE_FOLDER_ID=YOUR_EXISTING_FOLDER_ID
GOOGLE_APPLICATION_CREDENTIALS=/absolute/private/path/service-account.json
LEF_DATA_DIR=/absolute/writable/path/lef-cache
The service account needs access to the folder and permission to create/update files there. Shared Drive or ownership/quota restrictions can affect whether a service account can create the version 2 file. Resolve these in the Google Workspace configuration if the first save fails. Do not make the folder public.
The app first looks for lef-projects-v2.rds. If it does
not exist, it reads projects.rds in that exact folder and
creates the v2 file on first save. It never modifies the old file.
Duplicate filenames cause an explicit error. The supplied credential
JSON is deliberately not included in this package. Supply credentials
privately to the host; do not commit them to a public repo or place them
in a web-served directory.
Use ONE application instance with Drive mode. A file lock serialises saves on the same host/shared filesystem, and content checks reject stale sessions. These are NOT a distributed transaction: two independent instances or external Drive writers could race. For multi-instance hosting, use a transactional hosted PostgreSQL database in a later version. A local file lock does not fix that case.
If a Drive save reports a network failure, refresh before retrying: the remote write might have succeeded. The error does not imply the data was not written.
For a university server with durable disk, local mode is simple and supports multiple sessions using the same data directory. Set:
LEF_STORAGE=local
LEF_DATA_DIR=/durable/server/path/lef-projects
LEF_LEGACY_FILE=/path/to/original/projects.rds
Local atomic replacement is intended for POSIX/macOS/Linux filesystems. On Windows, replacement of an existing file may fail safely; use a Linux server or Drive mode if this occurs. Never use local mode as durable storage on a host that discards application files on restart/redeployment. For shinyapps.io, configure Drive persistence, private credentials, and single-instance hosting; do not assume local backups survive restarts. Hosting/access configuration must be verified in your own account before inviting lab members.
Each successful save attempt first writes a timestamped snapshot of
the previous state under LEF_DATA_DIR/backups/. A failed
save may also leave a backup. There is no automatic pruning. Keep that
directory on durable disk and include it in your institutional backup
policy. In Drive mode, those local snapshots are NOT uploaded to Drive.
Download full backups periodically for an independent copy.
To restore a trusted version 2 RDS backup:
LEF_DATA_DIR/lef-projects-v2.rds
with the backup. In Drive mode, update the contents of the exact
lef-projects-v2.rds file.Only use trusted RDS files. The interface does not accept arbitrary uploads.
One app.R file; no database installation required. Version 2 stores a
list with schema_version, projects, and
history. Project IDs are stable; duplicate names are
allowed and do not affect record identity. History records field
changes, notes, timestamps, and the name entered by the editor. Text is
escaped in cards/tables and links are restricted to HTTP(S).
Run the included checks from this folder with
Rscript tests.R. These cover legacy migration, local
persistence, stale-save rejection, and key server workflows. Google
Drive authentication and deployment need a live test in your
environment.
API references: https://googledrive.tidyverse.org/reference/drive_update.html and https://rstudio.github.io/DT/shiny.html