Documentation and Google Workspace: Practical Guide for Developers #
Introduction #
Documentation is an essential pillar of any software development project. It enables knowledge transfer, facilitates collaboration, and ensures code sustainability. In this article, we’ll explore how to use Google Workspace to create, organize, and maintain effective team documentation.
Why Document Effectively? #
The Four Pillars of Documentation #
graph TD
A[Effective Documentation] --> B[Understanding business context]
A --> C[Clarifying technical expectations]
A --> D[Facilitating estimation]
A --> E[Reducing back-and-forth]
B --> F[Time savings for the team]
C --> F
D --> F
E --> F
Essential Questions to Ask Yourself #
When writing documentation, systematically ask yourself these questions:
“What would a developer need to know?”
Considerations:
- What is the business context?
- What are the technical constraints?
- What are the external dependencies?
- What are the edge cases?
“What would I have liked to have been given to move forward faster?”
Useful elements:
- Concrete usage examples
- Architecture diagrams
- API specifications
- Test data
- Deployment procedures
Enabling Other Developers to Save Time #
Documentation should avoid wasting time during potential updates. Good documentation:
- Is maintainable over time
- Avoids redundancy
- Stays up-to-date with the code
- Is easily accessible
INVEST Methodology for Documentation #
INVEST Criteria Applied to Documentation #
The INVEST method, traditionally used for User Stories, also applies to documentation:
| Criterion | Description | Application to Documentation |
|---|---|---|
| Independent | Independent of others | Each document can be read separately |
| Negotiable | Negotiable | Content can be adjusted according to needs |
| Valuable | Has value in itself | Provides immediate value to the reader |
| Estimable | Estimable in terms of relative complexity | We can estimate writing time |
| Small | Small enough | One document covers one specific topic |
| Testable | Testable in principle | We can verify it’s written by writing a test |
Keeping Documentation Manageable #
“The user wants to change their notifications, create the preferences management page”
This user story can be broken down into documentation:
For necessity, each time you write what you’ve reported from modifications:
- When? (Modification date)
- Who? (Author of the modification)
- Why? (Reason for modification / link)
- What? (What was modified in terms of functionality)
- How? (Verify through the functionality process)
- Why? (To manage this modification)
User Stories and Complexity #
Structure of a User Story #
A User Story answers three fundamental questions:
As [WHO?]
I want [WHAT?]
In order to [WHY?]
Concrete example:
As an HR administrator
I want to export an employee profile to PDF
In order to generate contractual documents
Complexity Estimation #
The complexity of a User Story generally follows the Fibonacci sequence:
1, 2, 3, 5, 8, 13, 21…
| Complexity | Description | Example |
|---|---|---|
| 1 | Very simple, obvious | Label modification |
| 2 | Simple, little logic | Adding a field to a form |
| 3 | Moderately simple | Form validation with multiple rules |
| 5 | Moderate complexity | Creating a page with simple CRUD |
| 8 | Complex | Third-party API integration |
| 13 | Very complex | Complete module overhaul |
DoD (Definition of Done) and DoR (Definition of Ready) #
Definition of Ready (DoR) #
Criteria for a User Story to be ready for development:
- User Story written in “As… I want… In order to…” format
- Acceptance criteria defined
- Complexity estimated
- Dependencies identified
- Mockups available (if necessary)
Definition of Done (DoD) #
Criteria to consider a User Story complete:
- Code developed and tested
- Unit tests written and passing
- Documentation updated
- Code review performed
- Deployed to test environment
- Validated by Product Owner
Google Workspace for Documentation #
Use Case: User Story US-256 #
markdown[US-256] As an "HR Administrator"
I want to export an employee profile to PDF
In order to generate contractual documents
Business Context #
HR teams currently spend 2 hours per day copy-pasting employee information into Word “templates”. This improvement will save 80% of man-hours.
Scenarios #
“Successful Export” Scenario #
The user logs in with an administrator account They access the employee list They click “Export to PDF” for an employee The system generates a PDF with all information The PDF is automatically downloaded
“Missing Information” Scenario #
The user attempts to export an incomplete profile The system displays an error message The system lists the missing required fields
Design #
Technical elements to document:
- Libraries used (e.g., jsPDF, PDFKit)
- Dependency versions
- PDF template to use
- Data mapping
Tests #
Test data to prepare for both scenarios:
{
"scenario": "successful_export",
"employee": {
"id": "EMP001",
"firstName": "John",
"lastName": "Smith",
"email": "john.smith@example.com",
"position": "Senior Developer",
"department": "IT"
}
}
{
"scenario": "missing_information",
"employee": {
"id": "EMP002",
"firstName": "Mary",
"email": null,
"position": "Designer"
}
}
DoD Diagram (Definition of Done) #
graph TD
A[DoD - Definition of Done] --> B[Development]
A --> C[Tests]
A --> D[Documentation]
A --> E[Deployment]
B --> B1[Code written]
B --> B2[Code review OK]
C --> C1[Unit tests]
C --> C2[Integration tests]
D --> D1[README updated]
D --> D2[API documented]
E --> E1[Deployed to staging]
E --> E2[Validated by PO]
User Story Workflow #
sequenceDiagram
participant PO as Product Owner
participant Dev as Developer
participant QA as Quality Assurance
participant PM as Project Manager
PO->>PM: Writes User Story
PM->>Dev: Assigns task
Dev->>Dev: Develops feature
Dev->>QA: Requests validation
QA->>QA: Tests scenarios
alt Tests OK
QA->>PO: Requests business validation
PO->>PM: Validates and marks "Done"
else Tests KO
QA->>Dev: Returns with details
Dev->>Dev: Corrections
end
Advanced Google Sheets for Project Management #
Backlog Structure in Google Sheets #
“Params” Tab #
Create a tab to define reference values:
Rename the tab:
- Double-click on “Sheet 1”
- Rename to “Params”
Create named ranges:
Define DoD and DoR values:
Column A: DoD Types
- Code developed
- Unit tests written
- Documentation updated
- Code review performed
- Deployed to test
Column B: DoR Types
- User Story written
- Acceptance criteria defined
- Complexity estimated
- Dependencies identified
- Mockups available
Name a cell range:
- Select cells A2:A6
- Menu “Data” > “Named ranges”
- Name the range “DoD”
- Repeat for DoR (B2:B6)
“Backlog” Tab #
Backlog structure:
| ID | User Story | Complexity | DoR | DoD | Status | Assigned to |
|---|---|---|---|---|---|---|
| US-001 | As a… | 5 | ✓ | ☐ | In progress | Alice |
| US-002 | As a… | 3 | ✓ | ✓ | Complete | Bob |
Configure data validation:
- Select the “DoR” column
- Menu “Data” > “Data validation”
- Criteria: “List from a range”
- Range: “DoD” (the previously created named range)
- Repeat for “DoD” column
Useful Google Sheets Formulas #
Prior Configuration: Functions in English #
To use function names in English only:
- Menu “File” > “Settings”
- “Calculation” section
- Check “Always use English function names”
Basic Formulas #
Count the number of User Stories:
=COUNTA(A2:A50)
This formula counts all non-empty cells from A2 to A50.
Sum of total complexity:
=SUM(C2:C50)
Average complexity:
=AVERAGE(C2:C50)
Number of completed USs:
=COUNTIF(F2:F50, "Complete")
Advanced Formulas #
Completion percentage calculation:
=COUNTIF(F2:F50, "Complete") / COUNTA(A2:A50) * 100
Conditional filter (Alice’s in-progress USs):
=FILTER(A2:G50, G2:G50="Alice", F2:F50="In progress")
Total complexity per developer:
=SUMIF(G2:G50, "Alice", C2:C50)
Absolute References with F4 #
When entering a formula, press F4 to toggle between:
A1: Relative reference (changes when copied)$A$1: Absolute reference (never changes)$A1: Absolute column, relative rowA$1: Relative column, absolute row
Usage example:
=C2 * $H$1
If H1 contains the hourly rate, this formula calculates the cost of a task while always keeping the reference to H1.
Visual Dashboard #
Create a dashboard to track progress:
Pie chart (Statuses):
- Select “Status” and “ID” columns
- Menu “Insert” > “Chart”
- Type: Pie chart
- Customize colors
Bar chart (Complexity per developer):
These values come from Excel formulas:
- =SUMIF(G:G, “Alice”, C:C)
- =SUMIF(G:G, “Bob”, C:C)
- =SUMIF(G:G, “Charlie”, C:C)
Automation with Conditional Formatting
Color USs according to their status:
Select the “Status” column
Menu “Format” > “Conditional formatting”
- Rule 1: If “Complete” → Green
- Rule 2: If “In progress” → Orange
- Rule 3: If “To do” → Gray
Alert on high complexity:
Select the “Complexity” column
Menu “Format” > “Conditional formatting”
Rule: If value > 8 → Red
Google Apps Script for Automation #
Introduction to Google Apps Script #
Google Apps Script is a JavaScript-based scripting language that automates Google Workspace.
Access to the editor:
In Google Sheets: Menu “Extensions” > “Apps Script”
A new tab opens with the code editor
Apps Script Project Structure #
// Code.gs - Main file
/**
* Function executed when document loads
*/
function onOpen() {
const ui = SpreadsheetApp.getUi();
ui.createMenu('My Menu')
.addItem('Generate Report', 'generateReport')
.addItem('Export to PDF', 'exportToPDF')
.addToUi();
}
/**
* Generates a User Stories report
*/
function generateReport() {
const sheet = SpreadsheetApp.getActiveSheet();
const data = sheet.getDataRange().getValues();
// Data processing
Logger.log('Report generated');
}
Exercises #
Example 1: Automatic Velocity Calculation #
/**
* Calculates team velocity (completed points / sprint)
*/
function calculateVelocity() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Backlog');
const data = sheet.getDataRange().getValues();
let totalComplexity = 0;
let completedStories = 0;
// Iterate through rows (ignoring header)
for (let i = 1; i < data.length; i++) {
const status = data[i][5]; // "Status" column
const complexity = data[i][2]; // "Complexity" column
if (status === "Complete" && complexity) {
totalComplexity += parseInt(complexity);
completedStories++;
}
}
// Display result
const ui = SpreadsheetApp.getUi();
ui.alert(
'Team velocity',
`Completed stories: ${completedStories}\nTotal complexity: ${totalComplexity}`,
ui.ButtonSet.OK
);
return { completedStories, totalComplexity };
}
Example 2: Automatic PDF Export #
/**
* Exports backlog to PDF and sends it by email
*/
function exportBacklogToPDF() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('Backlog');
// Convert sheet to PDF
const url = ss.getUrl().replace(/edit/, 'export?format=pdf&gid=' + sheet.getSheetId());
const options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
}
};
const response = UrlFetchApp.fetch(url, options);
const blob = response.getBlob().setName('Backlog_' + new Date().toISOString().split('T')[0] + '.pdf');
// Send by email
GmailApp.sendEmail(
'manager@example.com',
'Backlog Export',
'Please find attached the backlog export.',
{
attachments: [blob]
}
);
SpreadsheetApp.getUi().alert('PDF exported and sent by email!');
}
Example 3: Automatic Notification #
/**
* Sends notification when a US is assigned
*/
function notifyOnAssignment() {
const sheet = SpreadsheetApp.getActiveSheet();
const range = sheet.getActiveRange();
// Check if modification concerns "Assigned to" column
if (range.getColumn() === 7) { // Column G
const assignedTo = range.getValue();
const row = range.getRow();
const usId = sheet.getRange(row, 1).getValue(); // Column A
const usTitle = sheet.getRange(row, 2).getValue(); // Column B
if (assignedTo) {
// Get developer's email (to adapt)
const email = getEmailByName(assignedTo);
if (email) {
GmailApp.sendEmail(
email,
`New User Story: ${usId}`,
`Hello ${assignedTo},\n\nThe following User Story has been assigned to you:\n\n${usId}: ${usTitle}\n\nHappy coding!`
);
}
}
}
}
/**
* Helper: Gets a developer's email by name
*/
function getEmailByName(name) {
const teamSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Team');
const data = teamSheet.getDataRange().getValues();
for (let i = 1; i < data.length; i++) {
if (data[i][0] === name) {
return data[i][1]; // Email in column B
}
}
return null;
}
Example 4: Automatic Date Update #
/**
* Automatically adds completion date
*/
function onEdit(e) {
const sheet = e.source.getActiveSheet();
const range = e.range;
// If "Status" column changes to "Complete"
if (range.getColumn() === 6 && range.getValue() === "Complete") {
const row = range.getRow();
const dateColumn = 8; // Column H: "End date"
sheet.getRange(row, dateColumn).setValue(new Date());
}
}
Script Deployment #
Deployment Steps #
In Apps Script editor: click “Deploy” > “New deployment” Type: “Add-on” Description: “Backlog Automation” Deploy
Manual Execution #
- Select function from dropdown list
- Click “Run”
- Authorize permissions the first time
Automatic Triggers #
- Clock (icon) in sidebar
- “+ Add trigger”
- Function: calculateVelocity
- Event source: “Time-driven”
- Type: “Hour timer”
- Interval: “Every week”
Best Practices #
Documentation #
The 5W + 1H Rule #
Always document according to this structure:
- Who: Who created/modified?
- What: What functionality?
- When: When was it developed?
- Where: Where is the code?
- Why: Why this implementation?
- How: How to use it?
Version Documentation #
In Google Sheets:
- Menu “File” > “Version history”
- “Name current version”
Example: “v1.0 - Sprint 3 - Added US-256 to US-280”
Keep Up-to-Date #
Create automatic reminder:
/**
* Sends weekly reminder to update documentation
*/
function sendDocumentationReminder() {
const recipients = [
'dev1@example.com',
'dev2@example.com'
];
recipients.forEach(email => {
GmailApp.sendEmail(
email,
'Reminder: Documentation update',
'Don\'t forget to update the backlog documentation this week!'
);
});
}
Trigger: Every Monday at 9am
Collaboration #
Document Sharing #
Permission levels:
- Viewer: Can only view
- Commenter: Can add comments
- Editor: Can modify content
Comments and Suggestions #
Use comments to:
- Request clarifications on a US
- Propose improvements
- Report issues
Shortcut: Ctrl + Alt + M (Windows) or Cmd + Option + M (Mac)
Notifications #
Configure notifications:
- File > “Notification settings”
- Choose “Notify me when… Changes are made”
- Frequency: “As they happen”
Performance #
Formula Optimization #
Avoid:
=COUNTIF(F2:F1000, "Complete") / COUNTA(A2:A1000)
Prefer (with named ranges):
=COUNTIF(Status, "Complete") / COUNTA(UserStories)
Limit Heavy Scripts #
For large processing:
function processLargeData() {
const sheet = SpreadsheetApp.getActiveSheet();
// Get all data at once
const data = sheet.getDataRange().getValues();
// Process in memory (fast)
const results = data.map(row => {
// Processing
return processedRow;
});
// Write results at once
sheet.getRange(1, 1, results.length, results[0].length).setValues(results);
}
Conclusion #
Summary #
Documentation and Google Workspace offer powerful synergy for:
| Aspect | Benefit |
|---|---|
| Collaboration | Real-time work on documents |
| Traceability | Version history and modifications |
| Automation | Scripts to save time |
| Accessibility | Available everywhere, on all devices |
| Integration | Connection with other Google tools |
Complete Workflow #
graph TD
A[User Story] --> B[Google Docs]
B --> C[Validation]
C --> D[Google Sheets Backlog]
D --> E[Apps Script]
E --> F[Notifications]
E --> G[Reports]
E --> H[PDF Export]
D --> I[Development]
I --> J[DoD Update]
J --> K[Final documentation]
Keys to Success #
- Document from the start (not after)
- Ask the right questions (Who? What? Why?)
- Use the right tools (Google Workspace)
- Automate repetitive tasks (Apps Script)
- Maintain regularly
- Collaborate actively