Work on correct protocol propagation
authorymh <ymh.work@gmail.com>
Thu, 03 Aug 2017 09:44:37 +0200
changeset 133 6f3078f7fd47
parent 132 906a6c7c7943
child 134 be36eed5e6e0
Work on correct protocol propagation
client/src/actions/sessionsActions.js
client/src/components/SessionForm.js
client/src/components/SessionList.js
client/src/sagas/SessionSyncronizer.js
client/src/sagas/groupSaga.js
client/src/store/groupRecord.js
design/api/metacategory.apib
design/api/metacategory.html
src/irinotes/settings.py
src/notes/api/fields/__init__.py
src/notes/api/fields/category.py
src/notes/api/serializers/auth.py
src/notes/api/serializers/core.py
src/notes/migrations/0001_initial.py
src/notes/models/auth.py
src/notes/models/category.py
--- a/client/src/actions/sessionsActions.js	Tue Aug 01 12:20:14 2017 +0200
+++ b/client/src/actions/sessionsActions.js	Thu Aug 03 09:44:37 2017 +0200
@@ -3,7 +3,7 @@
 import * as types from '../constants/actionTypes';
 
 
-export const createSession = (sessionId) => {
+export const createSession = (sessionId, groupName, protocol) => {
 
   const newSession = {
       _id: sessionId,
@@ -11,6 +11,8 @@
       date: now(),
       title: '',
       description: '',
+      group: groupName,
+      protocol: protocol,
       action: ActionEnum.CREATED
   };
 
--- a/client/src/components/SessionForm.js	Tue Aug 01 12:20:14 2017 +0200
+++ b/client/src/components/SessionForm.js	Thu Aug 03 09:44:37 2017 +0200
@@ -27,7 +27,9 @@
   onGroupChange = (e) => {
     const groupName = e.target.value;
 
-    this.props.sessionsActions.updateSession(this.props.currentSession, { group: groupName });
+    const group = this.props.groups.find((g) => g.get('name') === groupName);
+
+    this.props.sessionsActions.updateSession(this.props.currentSession, { group: groupName, protocol: group?group.get('protocol'):'' });
   }
 
   componentWillUpdate = (nextProps, nextState) => {
--- a/client/src/components/SessionList.js	Tue Aug 01 12:20:14 2017 +0200
+++ b/client/src/components/SessionList.js	Thu Aug 03 09:44:37 2017 +0200
@@ -18,7 +18,15 @@
 
   createSession = () => {
     const sessionId = uuidV1();
-    this.props.sessionsActions.createSession(sessionId);
+    const groupName = (this.props.currentUser)?this.props.currentUser.get('default_group'):null;
+    let protocol = null;
+    if(groupName != null) {
+      const group = this.props.groups.find((g) => g.name === groupName);
+      if(group) {
+        protocol = group.get('protocol');
+      }
+    }
+    this.props.sessionsActions.createSession(sessionId, groupName, protocol);
     this.props.history.push('/sessions/' + sessionId);
   }
 
@@ -86,13 +94,15 @@
 
 function mapStateToProps(state, props) {
   return {
-    sessions: state.get('sessions').filter(session => session.get('action') !== ActionEnum.DELETED)
+    sessions: state.get('sessions').filter(session => session.get('action') !== ActionEnum.DELETED),
+    currentUser: state.getIn(['authStatus', 'currentUser']),
+    groups: state.get('groups')
   };
 }
 
 function mapDispatchToProps(dispatch) {
   return {
-    sessionsActions: bindActionCreators(sessionsActions, dispatch)
+    sessionsActions: bindActionCreators(sessionsActions, dispatch),
   }
 }
 
--- a/client/src/sagas/SessionSyncronizer.js	Tue Aug 01 12:20:14 2017 +0200
+++ b/client/src/sagas/SessionSyncronizer.js	Thu Aug 03 09:44:37 2017 +0200
@@ -43,7 +43,7 @@
       title: localObjInst.get('title'),
       description: localObjInst.get('description'),
       group: localObjInst.get('group'),
-      protocol: ''
+      protocol: localObjInst.get('protocol'),
     };
   }
 
--- a/client/src/sagas/groupSaga.js	Tue Aug 01 12:20:14 2017 +0200
+++ b/client/src/sagas/groupSaga.js	Thu Aug 03 09:44:37 2017 +0200
@@ -25,7 +25,7 @@
 
       const actions = [
         groupCreateSuccess(response),
-        updateSession(session, {group: response.name})
+        updateSession(session, {group: response.name, protocol: response.protocol})
       ];
       yield all(actions.map(action => put(action)));
 
--- a/client/src/store/groupRecord.js	Tue Aug 01 12:20:14 2017 +0200
+++ b/client/src/store/groupRecord.js	Thu Aug 03 09:44:37 2017 +0200
@@ -5,6 +5,7 @@
 
   owner: '',
   isPersonal: false,
-  description:''
+  description:'',
+  protocol: null
 
 }, 'Group');
--- a/design/api/metacategory.apib	Tue Aug 01 12:20:14 2017 +0200
+++ b/design/api/metacategory.apib	Thu Aug 03 09:44:37 2017 +0200
@@ -39,7 +39,7 @@
 
 ## ProtocolRevisionFull (object)
 
-- Include MetacategoryRevision
+- Include ProtocolRevision
 - metacategories (array[MetacategoryRevision])
 
 
--- a/design/api/metacategory.html	Tue Aug 01 12:20:14 2017 +0200
+++ b/design/api/metacategory.html	Thu Aug 03 09:44:37 2017 +0200
@@ -68,13 +68,10 @@
     </span>}
   </span>}
 </span>}</code></pre><div style="height: 1px;"></div></div></div><div class="title"><strong>Response&nbsp;&nbsp;<code>201</code></strong><div class="collapse-button"><span class="close">Hide</span><span class="open">Show</span></div></div><div class="collapse-content"><div class="inner"><h5>Headers</h5><pre><code><span class="hljs-attribute">Content-Type</span>: <span class="hljs-string">application/json</span></code></pre><div style="height: 1px;"></div><h5>Body</h5><pre><code>{
-  "<span class="hljs-attribute">id</span>": <span class="hljs-value"><span class="hljs-string">"e5712a76-857a-4769-b27e-a3ac3fb38b4d"</span></span>,
-  "<span class="hljs-attribute">revision</span>": <span class="hljs-value"><span class="hljs-number">2</span></span>,
-  "<span class="hljs-attribute">base</span>": <span class="hljs-value"><span class="hljs-string">"ef14bcce-52ac-44ba-a7d1-f1441bab94de"</span></span>,
-  "<span class="hljs-attribute">name</span>": <span class="hljs-value"><span class="hljs-string">"référence"</span></span>,
-  "<span class="hljs-attribute">description</span>": <span class="hljs-value"><span class="hljs-string">"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin massa nibh, hendrerit quis justo vitae, luctus tempor dolor. Nam quis fringilla diam."</span></span>,
-  "<span class="hljs-attribute">color</span>": <span class="hljs-value"><span class="hljs-string">"#2cbfff"</span></span>,
-  "<span class="hljs-attribute">has_comment</span>": <span class="hljs-value"><span class="hljs-literal">false</span></span>,
+  "<span class="hljs-attribute">id</span>": <span class="hljs-value"><span class="hljs-string">"a4977c1f-4752-4aff-b724-eec4033af25c"</span></span>,
+  "<span class="hljs-attribute">owner</span>": <span class="hljs-value"><span class="hljs-string">"group1"</span></span>,
+  "<span class="hljs-attribute">revision</span>": <span class="hljs-value"><span class="hljs-string">"1"</span></span>,
+  "<span class="hljs-attribute">description</span>": <span class="hljs-value"><span class="hljs-string">"Cras rutrum lacinia pretium. Suspendisse justo est, tincidunt sed tellus a, sodales suscipit risus. Curabitur odio tortor, tincidunt sed est nec, ullamcorper sodales velit."</span></span>,
   "<span class="hljs-attribute">metacategories</span>": <span class="hljs-value">[
     {
       "<span class="hljs-attribute">id</span>": <span class="hljs-value"><span class="hljs-string">"e5712a76-857a-4769-b27e-a3ac3fb38b4d"</span></span>,
@@ -93,24 +90,15 @@
     "<span class="hljs-attribute">id</span>": <span class="hljs-value">{
       "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"string"</span>
     </span>}</span>,
-    "<span class="hljs-attribute">revision</span>": <span class="hljs-value">{
-      "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"number"</span>
-    </span>}</span>,
-    "<span class="hljs-attribute">base</span>": <span class="hljs-value">{
+    "<span class="hljs-attribute">owner</span>": <span class="hljs-value">{
       "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"string"</span>
     </span>}</span>,
-    "<span class="hljs-attribute">name</span>": <span class="hljs-value">{
+    "<span class="hljs-attribute">revision</span>": <span class="hljs-value">{
       "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"string"</span>
     </span>}</span>,
     "<span class="hljs-attribute">description</span>": <span class="hljs-value">{
       "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"string"</span>
     </span>}</span>,
-    "<span class="hljs-attribute">color</span>": <span class="hljs-value">{
-      "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"string"</span>
-    </span>}</span>,
-    "<span class="hljs-attribute">has_comment</span>": <span class="hljs-value">{
-      "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"boolean"</span>
-    </span>}</span>,
     "<span class="hljs-attribute">metacategories</span>": <span class="hljs-value">{
       "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"array"</span>
     </span>}
@@ -227,13 +215,10 @@
     </span>}
   </span>}
 </span>}</code></pre><div style="height: 1px;"></div></div></div><div class="title"><strong>Response&nbsp;&nbsp;<code>201</code></strong><div class="collapse-button"><span class="close">Hide</span><span class="open">Show</span></div></div><div class="collapse-content"><div class="inner"><h5>Headers</h5><pre><code><span class="hljs-attribute">Content-Type</span>: <span class="hljs-string">application/json</span></code></pre><div style="height: 1px;"></div><h5>Body</h5><pre><code>{
-  "<span class="hljs-attribute">id</span>": <span class="hljs-value"><span class="hljs-string">"e5712a76-857a-4769-b27e-a3ac3fb38b4d"</span></span>,
-  "<span class="hljs-attribute">revision</span>": <span class="hljs-value"><span class="hljs-number">2</span></span>,
-  "<span class="hljs-attribute">base</span>": <span class="hljs-value"><span class="hljs-string">"ef14bcce-52ac-44ba-a7d1-f1441bab94de"</span></span>,
-  "<span class="hljs-attribute">name</span>": <span class="hljs-value"><span class="hljs-string">"référence"</span></span>,
-  "<span class="hljs-attribute">description</span>": <span class="hljs-value"><span class="hljs-string">"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin massa nibh, hendrerit quis justo vitae, luctus tempor dolor. Nam quis fringilla diam."</span></span>,
-  "<span class="hljs-attribute">color</span>": <span class="hljs-value"><span class="hljs-string">"#2cbfff"</span></span>,
-  "<span class="hljs-attribute">has_comment</span>": <span class="hljs-value"><span class="hljs-literal">false</span></span>,
+  "<span class="hljs-attribute">id</span>": <span class="hljs-value"><span class="hljs-string">"a4977c1f-4752-4aff-b724-eec4033af25c"</span></span>,
+  "<span class="hljs-attribute">owner</span>": <span class="hljs-value"><span class="hljs-string">"group1"</span></span>,
+  "<span class="hljs-attribute">revision</span>": <span class="hljs-value"><span class="hljs-string">"1"</span></span>,
+  "<span class="hljs-attribute">description</span>": <span class="hljs-value"><span class="hljs-string">"Cras rutrum lacinia pretium. Suspendisse justo est, tincidunt sed tellus a, sodales suscipit risus. Curabitur odio tortor, tincidunt sed est nec, ullamcorper sodales velit."</span></span>,
   "<span class="hljs-attribute">metacategories</span>": <span class="hljs-value">[
     {
       "<span class="hljs-attribute">id</span>": <span class="hljs-value"><span class="hljs-string">"e5712a76-857a-4769-b27e-a3ac3fb38b4d"</span></span>,
@@ -252,24 +237,15 @@
     "<span class="hljs-attribute">id</span>": <span class="hljs-value">{
       "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"string"</span>
     </span>}</span>,
-    "<span class="hljs-attribute">revision</span>": <span class="hljs-value">{
-      "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"number"</span>
-    </span>}</span>,
-    "<span class="hljs-attribute">base</span>": <span class="hljs-value">{
+    "<span class="hljs-attribute">owner</span>": <span class="hljs-value">{
       "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"string"</span>
     </span>}</span>,
-    "<span class="hljs-attribute">name</span>": <span class="hljs-value">{
+    "<span class="hljs-attribute">revision</span>": <span class="hljs-value">{
       "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"string"</span>
     </span>}</span>,
     "<span class="hljs-attribute">description</span>": <span class="hljs-value">{
       "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"string"</span>
     </span>}</span>,
-    "<span class="hljs-attribute">color</span>": <span class="hljs-value">{
-      "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"string"</span>
-    </span>}</span>,
-    "<span class="hljs-attribute">has_comment</span>": <span class="hljs-value">{
-      "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"boolean"</span>
-    </span>}</span>,
     "<span class="hljs-attribute">metacategories</span>": <span class="hljs-value">{
       "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"array"</span>
     </span>}
@@ -300,13 +276,10 @@
 <h4>Example URI</h4><div class="definition"><span class="method get">GET</span>&nbsp;<span class="uri"><span class="hostname"></span>/protocol/<span class="hljs-attribute" title="id">a4977c1f-4752-4aff-b724-eec4033af25c</span>/<span class="hljs-attribute" title="revision">2</span>/</span></div><div class="title"><strong>URI Parameters</strong><div class="collapse-button show"><span class="close">Hide</span><span class="open">Show</span></div></div><div class="collapse-content"><dl class="inner"><dt>id</dt><dd><code>string</code>&nbsp;<span class="required">(required)</span>&nbsp;<span class="text-muted example"><strong>Example:&nbsp;</strong><span>a4977c1f-4752-4aff-b724-eec4033af25c</span></span><p>Identifiant d’un protocole</p>
 </dd><dt>revision</dt><dd><code>number</code>&nbsp;<span class="required">(required)</span>&nbsp;<span class="text-muted example"><strong>Example:&nbsp;</strong><span>2</span></span><p>Numéro de la révision</p>
 </dd></dl></div><div class="title"><strong>Response&nbsp;&nbsp;<code>200</code></strong><div class="collapse-button"><span class="close">Hide</span><span class="open">Show</span></div></div><div class="collapse-content"><div class="inner"><h5>Headers</h5><pre><code><span class="hljs-attribute">Content-Type</span>: <span class="hljs-string">application/json</span></code></pre><div style="height: 1px;"></div><h5>Body</h5><pre><code>{
-  "<span class="hljs-attribute">id</span>": <span class="hljs-value"><span class="hljs-string">"e5712a76-857a-4769-b27e-a3ac3fb38b4d"</span></span>,
-  "<span class="hljs-attribute">revision</span>": <span class="hljs-value"><span class="hljs-number">2</span></span>,
-  "<span class="hljs-attribute">base</span>": <span class="hljs-value"><span class="hljs-string">"ef14bcce-52ac-44ba-a7d1-f1441bab94de"</span></span>,
-  "<span class="hljs-attribute">name</span>": <span class="hljs-value"><span class="hljs-string">"référence"</span></span>,
-  "<span class="hljs-attribute">description</span>": <span class="hljs-value"><span class="hljs-string">"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin massa nibh, hendrerit quis justo vitae, luctus tempor dolor. Nam quis fringilla diam."</span></span>,
-  "<span class="hljs-attribute">color</span>": <span class="hljs-value"><span class="hljs-string">"#2cbfff"</span></span>,
-  "<span class="hljs-attribute">has_comment</span>": <span class="hljs-value"><span class="hljs-literal">false</span></span>,
+  "<span class="hljs-attribute">id</span>": <span class="hljs-value"><span class="hljs-string">"a4977c1f-4752-4aff-b724-eec4033af25c"</span></span>,
+  "<span class="hljs-attribute">owner</span>": <span class="hljs-value"><span class="hljs-string">"group1"</span></span>,
+  "<span class="hljs-attribute">revision</span>": <span class="hljs-value"><span class="hljs-string">"1"</span></span>,
+  "<span class="hljs-attribute">description</span>": <span class="hljs-value"><span class="hljs-string">"Cras rutrum lacinia pretium. Suspendisse justo est, tincidunt sed tellus a, sodales suscipit risus. Curabitur odio tortor, tincidunt sed est nec, ullamcorper sodales velit."</span></span>,
   "<span class="hljs-attribute">metacategories</span>": <span class="hljs-value">[
     {
       "<span class="hljs-attribute">id</span>": <span class="hljs-value"><span class="hljs-string">"e5712a76-857a-4769-b27e-a3ac3fb38b4d"</span></span>,
@@ -325,24 +298,15 @@
     "<span class="hljs-attribute">id</span>": <span class="hljs-value">{
       "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"string"</span>
     </span>}</span>,
-    "<span class="hljs-attribute">revision</span>": <span class="hljs-value">{
-      "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"number"</span>
-    </span>}</span>,
-    "<span class="hljs-attribute">base</span>": <span class="hljs-value">{
+    "<span class="hljs-attribute">owner</span>": <span class="hljs-value">{
       "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"string"</span>
     </span>}</span>,
-    "<span class="hljs-attribute">name</span>": <span class="hljs-value">{
+    "<span class="hljs-attribute">revision</span>": <span class="hljs-value">{
       "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"string"</span>
     </span>}</span>,
     "<span class="hljs-attribute">description</span>": <span class="hljs-value">{
       "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"string"</span>
     </span>}</span>,
-    "<span class="hljs-attribute">color</span>": <span class="hljs-value">{
-      "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"string"</span>
-    </span>}</span>,
-    "<span class="hljs-attribute">has_comment</span>": <span class="hljs-value">{
-      "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"boolean"</span>
-    </span>}</span>,
     "<span class="hljs-attribute">metacategories</span>": <span class="hljs-value">{
       "<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"array"</span>
     </span>}
@@ -429,7 +393,7 @@
     </span>}
   </span>}</span>,
   "<span class="hljs-attribute">$schema</span>": <span class="hljs-value"><span class="hljs-string">"http://json-schema.org/draft-04/schema#"</span>
-</span>}</code></pre><div style="height: 1px;"></div></div></div></div></div></section></div></div></div><p style="text-align: center;" class="text-muted">Generated by&nbsp;<a href="https://github.com/danielgtaylor/aglio" class="aglio">aglio</a>&nbsp;on 16 Jul 2017</p><script>/* eslint-env browser */
+</span>}</code></pre><div style="height: 1px;"></div></div></div></div></div></section></div></div></div><p style="text-align: center;" class="text-muted">Generated by&nbsp;<a href="https://github.com/danielgtaylor/aglio" class="aglio">aglio</a>&nbsp;on 01 Aug 2017</p><script>/* eslint-env browser */
 /* eslint quotes: [2, "single"] */
 'use strict';
 
--- a/src/irinotes/settings.py	Tue Aug 01 12:20:14 2017 +0200
+++ b/src/irinotes/settings.py	Thu Aug 03 09:44:37 2017 +0200
@@ -234,10 +234,15 @@
     'PAGE_SIZE': 100
 }
 
+# Rest auth settings
 REST_USE_JWT = True
+REST_AUTH_SERIALIZERS = {
+    'USER_DETAILS_SERIALIZER': 'notes.api.serializers.auth.UserDetailsSerializer'
+}
+
 OLD_PASSWORD_FIELD_ENABLED = True
 
-#JWT settings
+# JWT settings
 JWT_AUTH = {
     'JWT_ALLOW_REFRESH' : True,
     'JWT_EXPIRATION_DELTA' : datetime.timedelta(
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/notes/api/fields/category.py	Thu Aug 03 09:44:37 2017 +0200
@@ -0,0 +1,39 @@
+'''
+field serializing and deserializing metacategorization protocols
+'''
+import logging
+
+from rest_framework import serializers
+
+logger = logging.getLogger(__name__)
+
+class ProtocolField(serializers.Field):
+
+    def get_attribute(self, obj):
+        logger.debug("ProtocolField.get_attribute %r", obj)
+        # We pass the object instance onto `to_representation`,
+        # not just the field attribute.
+        return obj
+
+    def to_representation(self, obj):
+        logger.debug("ProtocolField.to_representation %r", obj)
+        return {
+            "id": "a4977c1f-4752-4aff-b724-eec4033af25c",
+            "owner": "group1",
+            "revision": "1",
+            "description": "Cras rutrum lacinia pretium. Suspendisse justo est, tincidunt sed tellus a, sodales suscipit risus. Curabitur odio tortor, tincidunt sed est nec, ullamcorper sodales velit.",
+            "metacategories": [{
+                "id": "e5712a76-857a-4769-b27e-a3ac3fb38b4d",
+                "revision": 2,
+                "base": "ef14bcce-52ac-44ba-a7d1-f1441bab94de",
+                "name": "référence",
+                "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin massa nibh, hendrerit quis justo vitae, luctus tempor dolor. Nam quis fringilla diam.",
+                "color": "#2cbfff",
+                "has_comment": False
+            }]
+        }
+
+    def to_internal_value(self, data):
+        logger.debug("ProtocolField.to_internal_value %r", data)
+        return "base protocol"
+
--- a/src/notes/api/serializers/auth.py	Tue Aug 01 12:20:14 2017 +0200
+++ b/src/notes/api/serializers/auth.py	Thu Aug 03 09:44:37 2017 +0200
@@ -2,8 +2,12 @@
 
 from django.contrib.auth import get_user_model
 from django.contrib.auth.models import Group
+from rest_auth.serializers import \
+    UserDetailsSerializer as RestAuthUserDetailsSerializer
 from rest_framework import serializers
 
+from notes.api.fields.category import ProtocolField
+
 logger = logging.getLogger(__name__)
 
 User = get_user_model()
@@ -12,10 +16,11 @@
     owner = serializers.CharField(source='profile.owner.username', read_only=True)
     is_personal = serializers.BooleanField(source='profile.is_personal', read_only=True)
     description = serializers.CharField(source='profile.description')
+    protocol = ProtocolField(read_only=True, source='profile.protocol')
 
     class Meta:
         model = Group
-        fields = ['name', 'owner', 'is_personal', 'description']
+        fields = ['name', 'owner', 'is_personal', 'description', 'protocol']
 
 
 class DetailGroupSerializer(GroupSerializer):
@@ -28,7 +33,7 @@
 
     class Meta:
         model = Group
-        fields = ['name', 'owner', 'description', 'users', 'is_personal']
+        fields = ['name', 'owner', 'description', 'users', 'is_personal', 'protocol']
 
 
 class WriteGroupSerializer(serializers.ModelSerializer):
@@ -44,10 +49,11 @@
         queryset=User.objects.all(),
         default=[]
     )
+    protocol = ProtocolField(required=False, source='profile.protocol')
 
     class Meta:
         model = Group
-        fields = ['name', 'description', 'users']
+        fields = ['name', 'description', 'users', 'protocol']
 
 
     def create(self, validated_data):
@@ -55,7 +61,7 @@
 
         group = super().create(validated_data)
 
-        if profile_data is not None:
+        if profile_data is not None and profile_data.get('description', None) is not None:
             group.profile.description = profile_data.get('description')
 
         user = None
@@ -73,7 +79,8 @@
         profile_data = validated_data.pop('profile', None)
         group = super().update(instance, validated_data)
 
-        if profile_data is not None:
+        logger.debug("WriteGroupSerializer.update %r", profile_data)
+        if profile_data is not None and profile_data.get('description', None) is not None:
             group.profile.description = profile_data.get('description')
             group.profile.save()
 
@@ -82,3 +89,11 @@
             group.user_set.add(group.profile.owner)
 
         return group
+
+
+class UserDetailsSerializer(RestAuthUserDetailsSerializer):
+    default_group = serializers.SlugRelatedField(read_only=True, slug_field='name', source='profile.default_group')
+
+    class Meta(RestAuthUserDetailsSerializer.Meta):
+        fields = ('pk', 'username', 'email', 'first_name', 'last_name', 'default_group')
+        read_only_fields = ('email', 'default_group')
--- a/src/notes/api/serializers/core.py	Tue Aug 01 12:20:14 2017 +0200
+++ b/src/notes/api/serializers/core.py	Thu Aug 03 09:44:37 2017 +0200
@@ -6,6 +6,7 @@
 from django.contrib.auth.models import Group
 from rest_framework import serializers
 
+from notes.api.fields.category import ProtocolField
 from notes.models import Note, Session
 
 logger = logging.getLogger(__name__)
@@ -90,6 +91,7 @@
     owner = serializers.SlugRelatedField(
         read_only=True, slug_field='username', default=serializers.CurrentUserDefault())
     group = serializers.SlugRelatedField(read_only=True, slug_field='name')
+    protocol = ProtocolField(required=False)
 
     class Meta:
         model = Session
@@ -97,7 +99,7 @@
             'ext_id', 'version', 'date', 'created', 'updated',
             'owner', 'title', 'description', 'protocol', 'group'
         )
-        read_only_fields = ('ext_id', 'version', 'created', 'updated', 'owner', 'group')
+        read_only_fields = ('ext_id', 'version', 'created', 'updated', 'owner', 'group', 'protocol')
 
 
 class DetailSessionSerializer(serializers.ModelSerializer):
@@ -105,6 +107,7 @@
     owner = serializers.SlugRelatedField(read_only=True, slug_field='username')
     notes = DetailNoteSerializer(many=True, read_only=True)
     group = serializers.SlugRelatedField(slug_field='name', read_only=True)
+    protocol = ProtocolField(required=False)
 
     class Meta:
         model = Session
@@ -113,13 +116,14 @@
             'owner', 'title', 'description', 'protocol', 'group',
             'notes'
         )
-        read_only_fields = ('ext_id', 'version', 'created', 'updated', 'owner', 'group')
+        read_only_fields = ('ext_id', 'version', 'created', 'updated', 'owner', 'group', 'protocol')
 
 class CreateSessionSerializer(serializers.ModelSerializer):
 
     owner = serializers.SlugRelatedField(
         read_only=True, slug_field='username', default=serializers.CurrentUserDefault())
-    group = serializers.SlugRelatedField(slug_field='name', queryset=Group.objects.all(), required=False)
+    group = serializers.SlugRelatedField(slug_field='name', queryset=Group.objects.all(), required=False, allow_null=True)
+    protocol = ProtocolField(required=False)
 
     class Meta:
         model = Session
@@ -148,4 +152,3 @@
 
         data['group'] = group
         return data
-
--- a/src/notes/migrations/0001_initial.py	Tue Aug 01 12:20:14 2017 +0200
+++ b/src/notes/migrations/0001_initial.py	Thu Aug 03 09:44:37 2017 +0200
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Generated by Django 1.11.2 on 2017-07-31 13:32
+# Generated by Django 1.11.2 on 2017-08-03 07:40
 from __future__ import unicode_literals
 
 import colorful.fields
@@ -66,6 +66,7 @@
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('description', models.TextField(blank=True, null=True)),
+                ('protocol', models.CharField(blank=True, max_length=512, null=True)),
                 ('group', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to='auth.Group')),
                 ('owner', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
                 ('owner_personal', models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='personal_group', to=settings.AUTH_USER_MODEL)),
@@ -106,7 +107,6 @@
                 ('ext_id', models.UUIDField(default=uuid.uuid4, unique=True, verbose_name='Model|ext_id')),
                 ('version', concurrency.fields.AutoIncVersionField(default=1, help_text='record revision number', verbose_name='Model|version')),
                 ('title', models.CharField(max_length=255, verbose_name='Protocol|title')),
-                ('group_profile', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='notes.GroupProfile')),
             ],
             options={
                 'verbose_name': 'Protocol',
--- a/src/notes/models/auth.py	Tue Aug 01 12:20:14 2017 +0200
+++ b/src/notes/models/auth.py	Thu Aug 03 09:44:37 2017 +0200
@@ -40,6 +40,7 @@
     # indicate that this group is a personal group.
     # used this instead of a boolean because it allows to easily enforce that a user has only one personal group
     owner_personal = models.OneToOneField(User, on_delete=models.CASCADE, null=True, related_name='personal_group')
+    protocol = models.CharField(max_length=512, null=True, blank=True)
 
     @property
     def is_personal(self):
--- a/src/notes/models/category.py	Tue Aug 01 12:20:14 2017 +0200
+++ b/src/notes/models/category.py	Thu Aug 03 09:44:37 2017 +0200
@@ -11,8 +11,8 @@
 
 class Protocol(Model):
     title = models.CharField(max_length=255, verbose_name=_('Protocol|title'))
-    group_profile = models.OneToOneField(
-        GroupProfile, on_delete=models.CASCADE)
+    # group_profile = models.OneToOneField(
+    #     GroupProfile, on_delete=models.CASCADE)
 
     class Meta:
         verbose_name = _('Protocol')