TBR: syncslides: Add schema.md file.

This is mostly a copy/paste of the schema.md from the old version of
syncslides.  The major difference is that this version calls for storing
UI state in syncbase.

Change-Id: I7ebc434a5a473e10e695c3e4765f3cb98e06171c
diff --git a/android/app/src/main/java/io/v/syncslides/db/schema.vdl b/android/app/src/main/java/io/v/syncslides/db/schema.vdl
index 4f290dc..5590bd4 100644
--- a/android/app/src/main/java/io/v/syncslides/db/schema.vdl
+++ b/android/app/src/main/java/io/v/syncslides/db/schema.vdl
@@ -4,13 +4,13 @@
 
 package db
 
-// Deck is the metadata for a set of slides.
+// VDeck is the metadata for a set of slides.
 type VDeck struct {
     Title string
     Thumbnail []byte
 }
 
-// Slide contains the image content for the slide.
+// VSlide contains the image content for the slide.
 type VSlide struct {
     // A low-res version of the image.
     Thumbnail []byte
@@ -20,37 +20,40 @@
     ImageRef string
 }
 
-// Note contains private-to-the-user notes for a specific slide.
+// VNote contains private-to-the-user notes for a specific slide.
 type VNote struct {
     Text string
 }
 
-// Presentation represents a live display of a Deck.
+// VPresentation represents a live display of a Deck.
 type VPresentation struct {
-    // If the presenter has handed control of the presentation to an audience member,
-    // driver will be present.  When the presenter takes back control, this
-    // will switch back to the empty string.
-    Driver ?VPerson  // ? means optional.
+    // Owner is responsible for advertising the presentation and has full
+    // control of it.
+    Owner VPerson
+    // Driver represents who has control of the presentation.  Usually, it is
+    // the presenter, but the presenter can give control to an audience member
+    // by changing this field.
+    Driver VPerson
 }
 
-// Person represents either an audience member or the presenter.
+// VPerson represents either an audience member or the presenter.
 type VPerson struct{
     Blessing string
     // The person's full name.
     Name string
 }
 
-// CurrentSlide contains state for the live presentation.  It is separate from the
-// Presentation so that the presenter can temporarily delegate control of the
-// CurrentSlide without giving up control of the entire presentation.
+// VCurrentSlide contains state for the live presentation.  It is separate from the
+// VPresentation so that the presenter can temporarily delegate control of the
+// VCurrentSlide without giving up control of the entire presentation.
 type VCurrentSlide struct {
     // The number of the slide that the presenter is talking about.
-    Num int32
+    SlideNum int32
     // In the future, we could add markup/doodles here.  That markup would be transient
     // if stored here.  Maybe better to put it in a separate row...
 }
 
-// Question represents a member of the audience asking a question of the presenter.
+// VQuestion represents a member of the audience asking a question of the presenter.
 // TODO(kash): Add support for the user to type in their question.  Right now, they
 // need to ask their question verbally.
 type VQuestion struct {
@@ -60,4 +63,21 @@
     Time int64
     // Track whether this question has been answered.
     Answered bool
+}
+
+// VSession represents UI state that most apps would consider to be ephemeral.
+// By storing it in Syncbase, we can resume a session on another device.
+// It also simplifies the Android implementation because we don't have to store
+// all of this state in a Bundle for each Activity/Fragment.
+type VSession struct {
+    DeckId string
+    PresentationId string
+    // When the user is not driving the presentation, he can go forward/back in
+    // the deck on his own.  A value of -1 means the user is following the
+    // driver of the presentation.
+    LocalSlide int32
+    // The time that this session was last used in milliseconds since the epoch.
+    // This field allows us to find the most recently used session and prompt
+    // the user to resume it.
+    LastTouched int64
 }
\ No newline at end of file
diff --git a/schema.md b/schema.md
new file mode 100644
index 0000000..9eca58b
--- /dev/null
+++ b/schema.md
@@ -0,0 +1,172 @@
+# Overview
+
+Syncslides uses Syncbase for data storage and communication between users'
+devices.
+
+# Detailed Design
+
+## Types
+
+All types are prefixed with 'V' because the Java version needs to have
+interfaces with similar names.
+
+```
+// VDeck is the metadata for a set of slides.
+type VDeck struct {
+  Title string
+  Thumbnail []byte
+}
+
+// VSlide contains the image content for the slide.
+type VSlide struct {
+  // A low-res version of the image stored as JPG.
+  Thumbnail []byte
+  // A high-res version of the image stored as JPG.
+  Fullsize Blobref  // NOTE: Not currently implemented.
+}
+
+// VNote contains private-to-the-user notes for a specific slide.
+type VNote struct {
+  Text string
+}
+
+// VPresentation represents a live display of a VDeck.
+type VPresentation struct {
+  // Owner is responsible for advertising the presentation and has full
+  // control of it.
+  Owner VPerson
+  // Driver represents who has control of the presentation.  Usually, it is
+  // the presenter, but the presenter can give control to an audience member
+  // by changing this field.
+  Driver VPerson
+}
+
+// VPerson represents either an audience member or the presenter.
+type VPerson struct {
+  Blessing string
+  // The person's full name.
+  Name string
+}
+
+// VCurrentSlide contains state for the live presentation.  It is separate
+// from the VPresentation so that the presenter can temporarily delegate
+// control of the VCurrentSlide without giving up control of the entire
+// presentation.
+type VCurrentSlide struct {
+  // The number of the slide that the presenter is talking about.
+  SlideNum int32
+  // In the future, we could add markup/doodles here.  That markup would be
+  // transient if stored here.  Maybe better to put it in a separate row...
+}
+
+// VQuestion represents a member of the audience asking a question of the
+// presenter. TODO(kash): Add support for the user to type in their question.
+// Right now, they need to ask their question verbally.
+type VQuestion struct {
+  // The person who asked the question.
+  Questioner VPerson
+  // Time when the question was asked in milliseconds since the epoch.
+  Time int64
+  // Track whether this question has been answered.
+  Answered bool
+}
+
+// VSession represents UI state that most apps would consider to be ephemeral.
+// By storing it in Syncbase, we can resume a session on another device.
+// It also simplifies the Android implementation because we don't have to store
+// all of this state in a Bundle for each Activity/Fragment.
+type VSession struct {
+  DeckId string
+  PresentationId string
+  // When the user is not driving the presentation, he can go forward/back in
+  // the deck on his own.  A value of -1 means the user is following the
+  // driver of the presentation.
+  LocalSlide int32
+  // The time that this session was last used in milliseconds since the epoch.
+  // This field allows us to find the most recently used session and prompt
+  // the user to resume it.
+  LastTouched int64
+}
+```
+
+## Table `Decks`
+
+A deck is a set of slides plus metadata.  It can be used in multiple
+presentations.  It is owned by the presenter, and the audience has read-only
+access.
+
+The deck is immutable because we use the simple scheme of ordering slides by
+their key (see example below).  The other tables refer to the slides by these
+hardcoded names, so those references would break if we allowed deck mutations.
+
+```
+<deckId>            --> VDeck
+<deckId>/slides/1   --> VSlide
+<deckId>/slides/2   --> VSlide
+<deckId>/slides/3   --> VSlide
+...
+```
+
+## Table `Notes`
+
+Notes are private to a user.  They are sparse in that if a user does not have
+any notes for a slide, the corresponding row is not present.
+
+The `lastViewed` row contains the timestamp that the user last viewed the
+presentation in milliseconds since the epoch. TODO(kash): Can we replace this
+with vdl.Time?  Does it work in Java?
+
+```
+<deckId>/LastViewed  --> int64
+<deckId>/slides/1    --> VNote
+<deckId>/slides/5    --> VNote
+```
+
+## Table `Presentations`
+
+A presentation represents a presenter displaying a deck to an audience.
+```
+<deckId>/<presentationId>                         --> VPresentation
+<deckId>/<presentationId>/CurrentSlide            --> VCurrentSlide
+<deckId>/<presentationId>/questions/<questionId>  --> VQuestion
+```
+
+## Table `UI`
+
+This table contains state that is specific to the UI.  It allows the user to
+resume on another device.
+
+```
+<sessionId>  --> VSession
+```
+
+## Syncgroups
+
+There are multiple syncgroups as part of a live presentation.
+* The presentation syncgroup contains:
+  * Table: Decks, Prefix: `<deckId>`
+    * ACL: Presenter: RWA, Audience: R
+  * Table: Presentation, Prefix: `<deckId>/<presentationId>`
+    * ACL: Presenter: RWA, Audience: R
+* The notes syncgroup contains:
+  * Table: Notes, Prefix: `<deckId>`
+    * ACL: Person who wrote the notes: RWA
+* The UI syncgroup contains:
+  * Table: UI, Prefix: ``  (Everything)
+    * ACL: The person who wrote the value: RWA
+
+## Delegation
+
+We want to be able to temporarily delegate control of the presentation to an
+audience member. The presenter will do this by writing the audience member's
+name to the VPresentation struct in the Presentations table.  The presenter
+will also set the ACL on the VCurrentSlide so that audience member can write
+it.  When the presenter wants control again, she will reverse these steps.
+
+## Questions
+
+When a user wants to ask a question, their device needs to write a VQuestion
+struct into the Presentations table.  The
+`<deckId>/<presentationId>/questions` prefix will be writable to everyone.
+When the questioner adds a question, they will also add an ACL just for that
+row.  The ACL will give write access to that user and to the presenter.